session-android/libsession/src/main/java/org/session/libsession/messaging/jobs/AttachmentDownloadJob.kt

130 lines
5.2 KiB
Kotlin
Raw Normal View History

2020-12-02 06:39:02 +01:00
package org.session.libsession.messaging.jobs
2020-11-25 02:06:41 +01:00
import android.content.ContentResolver
import android.media.MediaDataSource
import android.media.MediaExtractor
import okhttp3.HttpUrl
2021-04-26 03:14:45 +02:00
import org.session.libsession.messaging.MessagingModuleConfiguration
Merge remote-tracking branch 'upstream/dev' into open_groups_V2, working on compact poller implementation # Conflicts: # app/src/main/java/org/thoughtcrime/securesms/conversation/ConversationActivity.java # app/src/main/java/org/thoughtcrime/securesms/conversation/ConversationFragment.java # app/src/main/java/org/thoughtcrime/securesms/database/Storage.kt # app/src/main/java/org/thoughtcrime/securesms/loki/activities/HomeActivity.kt # app/src/main/java/org/thoughtcrime/securesms/loki/api/BackgroundPollWorker.kt # app/src/main/java/org/thoughtcrime/securesms/loki/api/PublicChatManager.kt # app/src/main/java/org/thoughtcrime/securesms/loki/database/LokiThreadDatabase.kt # app/src/main/java/org/thoughtcrime/securesms/loki/protocol/MultiDeviceProtocol.kt # app/src/main/java/org/thoughtcrime/securesms/loki/utilities/MentionManagerUtilities.kt # app/src/main/java/org/thoughtcrime/securesms/loki/utilities/OpenGroupUtilities.kt # app/src/main/java/org/thoughtcrime/securesms/loki/views/MentionCandidateView.kt # app/src/main/java/org/thoughtcrime/securesms/loki/views/ProfilePictureView.kt # libsession/src/main/java/org/session/libsession/messaging/StorageProtocol.kt # libsession/src/main/java/org/session/libsession/messaging/jobs/AttachmentDownloadJob.kt # libsession/src/main/java/org/session/libsession/messaging/jobs/AttachmentUploadJob.kt # libsession/src/main/java/org/session/libsession/messaging/mentions/MentionsManager.kt # libsession/src/main/java/org/session/libsession/messaging/messages/Destination.kt # libsession/src/main/java/org/session/libsession/messaging/open_groups/OpenGroupAPIV2.kt # libsession/src/main/java/org/session/libsession/messaging/open_groups/OpenGroupMessageV2.kt # libsession/src/main/java/org/session/libsession/messaging/open_groups/OpenGroupV2.kt # libsession/src/main/java/org/session/libsession/messaging/sending_receiving/MessageSender.kt # libsession/src/main/java/org/session/libsession/messaging/sending_receiving/ReceivedMessageHandler.kt # libsession/src/main/java/org/session/libsession/messaging/utilities/DotNetAPI.kt # libsession/src/main/java/org/session/libsession/snode/OnionRequestAPI.kt # libsession/src/main/java/org/session/libsession/snode/SnodeAPI.kt # libsession/src/main/java/org/session/libsession/snode/SnodeMessage.kt # libsession/src/main/java/org/session/libsession/utilities/mentions/MentionsManager.kt # libsignal/src/main/java/org/session/libsignal/service/loki/api/SwarmAPI.kt # libsignal/src/main/java/org/session/libsignal/service/loki/api/opengroups/PublicChat.kt # libsignal/src/main/java/org/session/libsignal/service/loki/utilities/mentions/MentionsManager.kt
2021-04-28 09:41:30 +02:00
import org.session.libsession.messaging.open_groups.OpenGroupAPIV2
2021-01-05 04:17:42 +01:00
import org.session.libsession.messaging.sending_receiving.attachments.AttachmentState
2021-05-13 02:31:06 +02:00
import org.session.libsession.messaging.utilities.Data
import org.session.libsession.utilities.DecodedAudio
import org.session.libsession.utilities.DownloadUtilities
import org.session.libsession.utilities.FileUtils
import org.session.libsession.utilities.InputStreamMediaDataSource
2021-05-18 01:21:56 +02:00
import org.session.libsignal.streams.AttachmentCipherInputStream
import org.session.libsignal.utilities.Base64
2021-05-18 01:12:33 +02:00
import org.session.libsignal.utilities.Log
2021-01-05 04:17:42 +01:00
import java.io.File
import java.io.FileDescriptor
2021-01-05 04:17:42 +01:00
import java.io.FileInputStream
class AttachmentDownloadJob(val attachmentID: Long, val databaseMessageID: Long) : Job {
2020-12-02 06:39:02 +01:00
override var delegate: JobDelegate? = null
override var id: String? = null
override var failureCount: Int = 0
2021-01-05 04:17:42 +01:00
// Error
internal sealed class Error(val description: String) : Exception(description) {
2021-01-05 04:17:42 +01:00
object NoAttachment : Error("No such attachment.")
}
2020-12-02 06:39:02 +01:00
// Settings
override val maxFailureCount: Int = 100
2020-12-02 06:39:02 +01:00
companion object {
2021-01-28 05:24:27 +01:00
val KEY: String = "AttachmentDownloadJob"
2021-04-26 02:58:48 +02:00
// Keys used for database storage
2021-05-12 08:17:25 +02:00
private val ATTACHMENT_ID_KEY = "attachment_id"
private val TS_INCOMING_MESSAGE_ID_KEY = "tsIncoming_message_id"
2020-12-02 06:39:02 +01:00
}
override fun execute() {
val storage = MessagingModuleConfiguration.shared.storage
val messageDataProvider = MessagingModuleConfiguration.shared.messageDataProvider
val handleFailure: (java.lang.Exception) -> Unit = { exception ->
2021-04-26 02:58:48 +02:00
if (exception == Error.NoAttachment) {
messageDataProvider.setAttachmentState(AttachmentState.FAILED, attachmentID, databaseMessageID)
this.handlePermanentFailure(exception)
} else {
this.handleFailure(exception)
}
}
2021-01-05 04:17:42 +01:00
try {
val attachment = messageDataProvider.getDatabaseAttachment(attachmentID)
2021-05-12 08:17:25 +02:00
?: return handleFailure(Error.NoAttachment)
messageDataProvider.setAttachmentState(AttachmentState.STARTED, attachmentID, this.databaseMessageID)
val tempFile = createTempFile()
val threadID = storage.getThreadIdForMms(databaseMessageID)
2021-05-21 07:02:34 +02:00
val openGroupV2 = storage.getV2OpenGroup(threadID)
val inputStream = if (openGroupV2 == null) {
2021-05-21 07:02:34 +02:00
DownloadUtilities.downloadFile(tempFile, attachment.url)
// Assume we're retrieving an attachment for an open group server if the digest is not set
2021-05-12 08:17:25 +02:00
if (attachment.digest?.size ?: 0 == 0 || attachment.key.isNullOrEmpty()) {
FileInputStream(tempFile)
} else {
AttachmentCipherInputStream.createForAttachment(tempFile, attachment.size, Base64.decode(attachment.key), attachment.digest)
}
} else {
val url = HttpUrl.parse(attachment.url)!!
val fileID = url.pathSegments().last()
OpenGroupAPIV2.download(fileID.toLong(), openGroupV2.room, openGroupV2.server).get().let {
tempFile.writeBytes(it)
}
FileInputStream(tempFile)
}
if (attachment.contentType.startsWith("audio/")) {
// process the duration
InputStreamMediaDataSource(inputStream).use { mediaDataSource ->
val durationMs = (DecodedAudio.create(mediaDataSource).totalDuration / 1000.0).toLong()
messageDataProvider.updateAudioAttachmentDuration(attachment.attachmentId, durationMs)
}
}
messageDataProvider.insertAttachment(databaseMessageID, attachment.attachmentId, inputStream)
tempFile.delete()
handleSuccess()
} catch (e: Exception) {
return handleFailure(e)
}
2021-01-05 04:17:42 +01:00
}
private fun handleSuccess() {
Log.w(AttachmentUploadJob.TAG, "Attachment downloaded successfully.")
2021-01-05 04:17:42 +01:00
delegate?.handleJobSucceeded(this)
}
private fun handlePermanentFailure(e: Exception) {
delegate?.handleJobFailedPermanently(this, e)
}
private fun handleFailure(e: Exception) {
delegate?.handleJobFailed(this, e)
}
private fun createTempFile(): File {
2021-04-26 03:14:45 +02:00
val file = File.createTempFile("push-attachment", "tmp", MessagingModuleConfiguration.shared.context.cacheDir)
2021-01-05 04:17:42 +01:00
file.deleteOnExit()
return file
2020-12-02 06:39:02 +01:00
}
2021-01-22 05:19:41 +01:00
override fun serialize(): Data {
2021-05-12 08:17:25 +02:00
return Data.Builder()
.putLong(ATTACHMENT_ID_KEY, attachmentID)
.putLong(TS_INCOMING_MESSAGE_ID_KEY, databaseMessageID)
2021-04-26 02:58:48 +02:00
.build();
}
2021-01-28 05:24:27 +01:00
override fun getFactoryKey(): String {
return KEY
}
class Factory : Job.Factory<AttachmentDownloadJob> {
2021-05-12 08:17:25 +02:00
2021-01-22 05:19:41 +01:00
override fun create(data: Data): AttachmentDownloadJob {
2021-05-12 08:17:25 +02:00
return AttachmentDownloadJob(data.getLong(ATTACHMENT_ID_KEY), data.getLong(TS_INCOMING_MESSAGE_ID_KEY))
}
}
2020-11-25 02:06:41 +01:00
}