mirror of
https://github.com/signalapp/Signal-Android.git
synced 2026-03-02 15:36:32 +00:00
Add IV to the attachment table.
This commit is contained in:
committed by
Cody Henthorne
parent
07289b417b
commit
4b47d38d78
@@ -32,6 +32,7 @@ class ArchivedAttachment : Attachment {
|
||||
size: Long,
|
||||
cdn: Int,
|
||||
key: ByteArray,
|
||||
iv: ByteArray?,
|
||||
cdnKey: String?,
|
||||
archiveCdn: Int?,
|
||||
archiveMediaName: String,
|
||||
@@ -60,6 +61,7 @@ class ArchivedAttachment : Attachment {
|
||||
cdn = Cdn.fromCdnNumber(cdn),
|
||||
remoteLocation = cdnKey,
|
||||
remoteKey = Base64.encodeWithoutPadding(key),
|
||||
remoteIv = iv,
|
||||
remoteDigest = digest,
|
||||
incrementalDigest = incrementalMac,
|
||||
fastPreflightId = null,
|
||||
|
||||
@@ -37,6 +37,8 @@ abstract class Attachment(
|
||||
@JvmField
|
||||
val remoteKey: String?,
|
||||
@JvmField
|
||||
val remoteIv: ByteArray?,
|
||||
@JvmField
|
||||
val remoteDigest: ByteArray?,
|
||||
@JvmField
|
||||
val incrementalDigest: ByteArray?,
|
||||
@@ -86,6 +88,7 @@ abstract class Attachment(
|
||||
cdn = Cdn.deserialize(parcel.readInt()),
|
||||
remoteLocation = parcel.readString(),
|
||||
remoteKey = parcel.readString(),
|
||||
remoteIv = ParcelUtil.readByteArray(parcel),
|
||||
remoteDigest = ParcelUtil.readByteArray(parcel),
|
||||
incrementalDigest = ParcelUtil.readByteArray(parcel),
|
||||
fastPreflightId = parcel.readString(),
|
||||
|
||||
@@ -58,6 +58,7 @@ class DatabaseAttachment : Attachment {
|
||||
cdn: Cdn,
|
||||
location: String?,
|
||||
key: String?,
|
||||
iv: ByteArray?,
|
||||
digest: ByteArray?,
|
||||
incrementalDigest: ByteArray?,
|
||||
incrementalMacChunkSize: Int,
|
||||
@@ -90,6 +91,7 @@ class DatabaseAttachment : Attachment {
|
||||
cdn = cdn,
|
||||
remoteLocation = location,
|
||||
remoteKey = key,
|
||||
remoteIv = iv,
|
||||
remoteDigest = digest,
|
||||
incrementalDigest = incrementalDigest,
|
||||
fastPreflightId = fastPreflightId,
|
||||
|
||||
@@ -3,7 +3,7 @@ package org.thoughtcrime.securesms.attachments
|
||||
import android.net.Uri
|
||||
import android.os.Parcel
|
||||
import androidx.annotation.VisibleForTesting
|
||||
import org.signal.core.util.Base64.encodeWithPadding
|
||||
import org.signal.core.util.Base64
|
||||
import org.thoughtcrime.securesms.blurhash.BlurHash
|
||||
import org.thoughtcrime.securesms.database.AttachmentTable
|
||||
import org.thoughtcrime.securesms.stickers.StickerLocator
|
||||
@@ -24,6 +24,7 @@ class PointerAttachment : Attachment {
|
||||
cdn: Cdn,
|
||||
location: String,
|
||||
key: String?,
|
||||
iv: ByteArray?,
|
||||
digest: ByteArray?,
|
||||
incrementalDigest: ByteArray?,
|
||||
incrementalMacChunkSize: Int,
|
||||
@@ -46,6 +47,7 @@ class PointerAttachment : Attachment {
|
||||
cdn = cdn,
|
||||
remoteLocation = location,
|
||||
remoteKey = key,
|
||||
remoteIv = iv,
|
||||
remoteDigest = digest,
|
||||
incrementalDigest = incrementalDigest,
|
||||
fastPreflightId = fastPreflightId,
|
||||
@@ -86,12 +88,17 @@ class PointerAttachment : Attachment {
|
||||
|
||||
@JvmStatic
|
||||
@JvmOverloads
|
||||
fun forPointer(pointer: Optional<SignalServiceAttachment>, stickerLocator: StickerLocator? = null, fastPreflightId: String? = null, transferState: Int = AttachmentTable.TRANSFER_PROGRESS_PENDING): Optional<Attachment> {
|
||||
fun forPointer(
|
||||
pointer: Optional<SignalServiceAttachment>,
|
||||
stickerLocator: StickerLocator? = null,
|
||||
fastPreflightId: String? = null,
|
||||
transferState: Int = AttachmentTable.TRANSFER_PROGRESS_PENDING
|
||||
): Optional<Attachment> {
|
||||
if (!pointer.isPresent || !pointer.get().isPointer()) {
|
||||
return Optional.empty()
|
||||
}
|
||||
|
||||
val encodedKey: String? = pointer.get().asPointer().key?.let { encodeWithPadding(it) }
|
||||
val encodedKey: String? = pointer.get().asPointer().key?.let { Base64.encodeWithPadding(it) }
|
||||
|
||||
return Optional.of(
|
||||
PointerAttachment(
|
||||
@@ -102,6 +109,7 @@ class PointerAttachment : Attachment {
|
||||
cdn = Cdn.fromCdnNumber(pointer.get().asPointer().cdnNumber),
|
||||
location = pointer.get().asPointer().remoteId.toString(),
|
||||
key = encodedKey,
|
||||
iv = null,
|
||||
digest = pointer.get().asPointer().digest.orElse(null),
|
||||
incrementalDigest = pointer.get().asPointer().incrementalDigest.orElse(null),
|
||||
incrementalMacChunkSize = pointer.get().asPointer().incrementalMacChunkSize,
|
||||
@@ -139,7 +147,8 @@ class PointerAttachment : Attachment {
|
||||
fileName = quotedAttachment.fileName,
|
||||
cdn = Cdn.fromCdnNumber(thumbnail?.asPointer()?.cdnNumber ?: 0),
|
||||
location = thumbnail?.asPointer()?.remoteId?.toString() ?: "0",
|
||||
key = thumbnail?.asPointer()?.key?.let { encodeWithPadding(it) },
|
||||
key = thumbnail?.asPointer()?.key?.let { Base64.encodeWithPadding(it) },
|
||||
iv = null,
|
||||
digest = thumbnail?.asPointer()?.digest?.orElse(null),
|
||||
incrementalDigest = thumbnail?.asPointer()?.incrementalDigest?.orElse(null),
|
||||
incrementalMacChunkSize = thumbnail?.asPointer()?.incrementalMacChunkSize ?: 0,
|
||||
|
||||
@@ -22,6 +22,7 @@ class TombstoneAttachment : Attachment {
|
||||
cdn = Cdn.CDN_0,
|
||||
remoteLocation = null,
|
||||
remoteKey = null,
|
||||
remoteIv = null,
|
||||
remoteDigest = null,
|
||||
incrementalDigest = null,
|
||||
fastPreflightId = null,
|
||||
@@ -62,6 +63,7 @@ class TombstoneAttachment : Attachment {
|
||||
cdn = Cdn.CDN_0,
|
||||
remoteLocation = null,
|
||||
remoteKey = null,
|
||||
remoteIv = null,
|
||||
remoteDigest = null,
|
||||
incrementalDigest = incrementalMac,
|
||||
fastPreflightId = null,
|
||||
|
||||
@@ -75,6 +75,7 @@ class UriAttachment : Attachment {
|
||||
cdn = Cdn.CDN_0,
|
||||
remoteLocation = null,
|
||||
remoteKey = null,
|
||||
remoteIv = null,
|
||||
remoteDigest = null,
|
||||
incrementalDigest = null,
|
||||
fastPreflightId = fastPreflightId,
|
||||
|
||||
@@ -1030,6 +1030,7 @@ class ChatItemImportInserter(
|
||||
size = this.backupLocator.size.toLong(),
|
||||
cdn = this.backupLocator.transitCdnNumber ?: Cdn.CDN_0.cdnNumber,
|
||||
key = this.backupLocator.key.toByteArray(),
|
||||
iv = null,
|
||||
cdnKey = this.backupLocator.transitCdnKey,
|
||||
archiveCdn = this.backupLocator.cdnNumber,
|
||||
archiveMediaName = this.backupLocator.mediaName,
|
||||
|
||||
@@ -90,7 +90,9 @@ import org.thoughtcrime.securesms.util.FileUtils
|
||||
import org.thoughtcrime.securesms.util.JsonUtils.SaneJSONObject
|
||||
import org.thoughtcrime.securesms.util.MediaUtil
|
||||
import org.thoughtcrime.securesms.util.StorageUtil
|
||||
import org.thoughtcrime.securesms.util.Util
|
||||
import org.thoughtcrime.securesms.video.EncryptedMediaDataSource
|
||||
import org.whispersystems.signalservice.api.attachment.AttachmentUploadResult
|
||||
import org.whispersystems.signalservice.api.util.UuidUtil
|
||||
import org.whispersystems.signalservice.internal.util.JsonUtil
|
||||
import java.io.File
|
||||
@@ -118,6 +120,7 @@ class AttachmentTable(
|
||||
const val MESSAGE_ID = "message_id"
|
||||
const val CONTENT_TYPE = "content_type"
|
||||
const val REMOTE_KEY = "remote_key"
|
||||
const val REMOTE_IV = "remote_iv"
|
||||
const val REMOTE_LOCATION = "remote_location"
|
||||
const val REMOTE_DIGEST = "remote_digest"
|
||||
const val REMOTE_INCREMENTAL_DIGEST = "remote_incremental_digest"
|
||||
@@ -178,6 +181,7 @@ class AttachmentTable(
|
||||
MESSAGE_ID,
|
||||
CONTENT_TYPE,
|
||||
REMOTE_KEY,
|
||||
REMOTE_IV,
|
||||
REMOTE_LOCATION,
|
||||
REMOTE_DIGEST,
|
||||
REMOTE_INCREMENTAL_DIGEST,
|
||||
@@ -263,7 +267,8 @@ class AttachmentTable(
|
||||
$THUMBNAIL_FILE TEXT DEFAULT NULL,
|
||||
$THUMBNAIL_RANDOM BLOB DEFAULT NULL,
|
||||
$THUMBNAIL_RESTORE_STATE INTEGER DEFAULT ${ThumbnailRestoreState.NONE.value},
|
||||
$ATTACHMENT_UUID TEXT DEFAULT NULL
|
||||
$ATTACHMENT_UUID TEXT DEFAULT NULL,
|
||||
$REMOTE_IV BLOB DEFAULT NULL
|
||||
)
|
||||
"""
|
||||
|
||||
@@ -1026,7 +1031,7 @@ class AttachmentTable(
|
||||
* it's ending hash, which is critical for backups.
|
||||
*/
|
||||
@Throws(IOException::class)
|
||||
fun finalizeAttachmentAfterUpload(id: AttachmentId, attachment: Attachment, uploadTimestamp: Long) {
|
||||
fun finalizeAttachmentAfterUpload(id: AttachmentId, uploadResult: AttachmentUploadResult) {
|
||||
Log.i(TAG, "[finalizeAttachmentAfterUpload] Finalizing upload for $id.")
|
||||
|
||||
val dataStream = getAttachmentStream(id, 0)
|
||||
@@ -1040,17 +1045,14 @@ class AttachmentTable(
|
||||
|
||||
val values = contentValuesOf(
|
||||
TRANSFER_STATE to TRANSFER_PROGRESS_DONE,
|
||||
CDN_NUMBER to attachment.cdn.serialize(),
|
||||
REMOTE_LOCATION to attachment.remoteLocation,
|
||||
REMOTE_DIGEST to attachment.remoteDigest,
|
||||
REMOTE_INCREMENTAL_DIGEST to attachment.incrementalDigest,
|
||||
REMOTE_INCREMENTAL_DIGEST_CHUNK_SIZE to attachment.incrementalMacChunkSize,
|
||||
REMOTE_KEY to attachment.remoteKey,
|
||||
DATA_SIZE to attachment.size,
|
||||
CDN_NUMBER to uploadResult.cdnNumber,
|
||||
REMOTE_LOCATION to uploadResult.remoteId.toString(),
|
||||
REMOTE_DIGEST to uploadResult.digest,
|
||||
REMOTE_INCREMENTAL_DIGEST to uploadResult.incrementalDigest,
|
||||
REMOTE_INCREMENTAL_DIGEST_CHUNK_SIZE to uploadResult.incrementalDigestChunkSize,
|
||||
DATA_SIZE to uploadResult.dataSize,
|
||||
DATA_HASH_END to dataHashEnd,
|
||||
FAST_PREFLIGHT_ID to attachment.fastPreflightId,
|
||||
BLUR_HASH to attachment.getVisualHashStringOrNull(),
|
||||
UPLOAD_TIMESTAMP to uploadTimestamp
|
||||
UPLOAD_TIMESTAMP to uploadResult.uploadTimestamp
|
||||
)
|
||||
|
||||
val dataFilePath = getDataFilePath(id) ?: throw IOException("No data file found for attachment!")
|
||||
@@ -1153,6 +1155,25 @@ class AttachmentTable(
|
||||
}
|
||||
}
|
||||
|
||||
fun createKeyIvIfNecessary(attachmentId: AttachmentId) {
|
||||
val key = Util.getSecretBytes(64)
|
||||
val iv = Util.getSecretBytes(16)
|
||||
|
||||
writableDatabase.withinTransaction {
|
||||
writableDatabase
|
||||
.update(TABLE_NAME)
|
||||
.values(REMOTE_KEY to Base64.encodeWithPadding(key))
|
||||
.where("$ID = ? AND $REMOTE_KEY IS NULL", attachmentId.id)
|
||||
.run()
|
||||
|
||||
writableDatabase
|
||||
.update(TABLE_NAME)
|
||||
.values(REMOTE_IV to iv)
|
||||
.where("$ID = ? AND $REMOTE_IV IS NULL", attachmentId.id)
|
||||
.run()
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Inserts new attachments in the table. The [Attachment]s may or may not have data, depending on whether it's an attachment we created locally or some
|
||||
* inbound attachment that we haven't fetched yet.
|
||||
@@ -1507,6 +1528,7 @@ class AttachmentTable(
|
||||
cdn = Cdn.deserialize(jsonObject.getInt(CDN_NUMBER)),
|
||||
location = jsonObject.getString(REMOTE_LOCATION),
|
||||
key = jsonObject.getString(REMOTE_KEY),
|
||||
iv = null,
|
||||
digest = null,
|
||||
incrementalDigest = null,
|
||||
incrementalMacChunkSize = 0,
|
||||
@@ -2040,6 +2062,7 @@ class AttachmentTable(
|
||||
contentValues.put(REMOTE_INCREMENTAL_DIGEST, uploadTemplate?.incrementalDigest)
|
||||
contentValues.put(REMOTE_INCREMENTAL_DIGEST_CHUNK_SIZE, uploadTemplate?.incrementalMacChunkSize ?: 0)
|
||||
contentValues.put(REMOTE_KEY, uploadTemplate?.remoteKey)
|
||||
contentValues.put(REMOTE_IV, uploadTemplate?.remoteIv)
|
||||
contentValues.put(FILE_NAME, StorageUtil.getCleanFileName(attachment.fileName))
|
||||
contentValues.put(FAST_PREFLIGHT_ID, attachment.fastPreflightId)
|
||||
contentValues.put(VOICE_NOTE, if (attachment.voiceNote) 1 else 0)
|
||||
@@ -2120,6 +2143,7 @@ class AttachmentTable(
|
||||
cdn = cursor.requireObject(CDN_NUMBER, Cdn.Serializer),
|
||||
location = cursor.requireString(REMOTE_LOCATION),
|
||||
key = cursor.requireString(REMOTE_KEY),
|
||||
iv = cursor.requireBlob(REMOTE_IV),
|
||||
digest = cursor.requireBlob(REMOTE_DIGEST),
|
||||
incrementalDigest = cursor.requireBlob(REMOTE_INCREMENTAL_DIGEST),
|
||||
incrementalMacChunkSize = cursor.requireInt(REMOTE_INCREMENTAL_DIGEST_CHUNK_SIZE),
|
||||
|
||||
@@ -101,6 +101,7 @@ import org.thoughtcrime.securesms.database.helpers.migration.V240_MessageFullTex
|
||||
import org.thoughtcrime.securesms.database.helpers.migration.V241_ExpireTimerVersion
|
||||
import org.thoughtcrime.securesms.database.helpers.migration.V242_MessageFullTextSearchEmojiSupportV2
|
||||
import org.thoughtcrime.securesms.database.helpers.migration.V243_MessageFullTextSearchDisableSecureDelete
|
||||
import org.thoughtcrime.securesms.database.helpers.migration.V244_AttachmentRemoteIv
|
||||
|
||||
/**
|
||||
* Contains all of the database migrations for [SignalDatabase]. Broken into a separate file for cleanliness.
|
||||
@@ -204,10 +205,11 @@ object SignalDatabaseMigrations {
|
||||
240 to V240_MessageFullTextSearchSecureDelete,
|
||||
241 to V241_ExpireTimerVersion,
|
||||
242 to V242_MessageFullTextSearchEmojiSupportV2,
|
||||
243 to V243_MessageFullTextSearchDisableSecureDelete
|
||||
243 to V243_MessageFullTextSearchDisableSecureDelete,
|
||||
244 to V244_AttachmentRemoteIv
|
||||
)
|
||||
|
||||
const val DATABASE_VERSION = 243
|
||||
const val DATABASE_VERSION = 244
|
||||
|
||||
@JvmStatic
|
||||
fun migrate(context: Application, db: SQLiteDatabase, oldVersion: Int, newVersion: Int) {
|
||||
|
||||
@@ -0,0 +1,18 @@
|
||||
/*
|
||||
* Copyright 2024 Signal Messenger, LLC
|
||||
* SPDX-License-Identifier: AGPL-3.0-only
|
||||
*/
|
||||
|
||||
package org.thoughtcrime.securesms.database.helpers.migration
|
||||
|
||||
import android.app.Application
|
||||
import net.zetetic.database.sqlcipher.SQLiteDatabase
|
||||
|
||||
/**
|
||||
* Adds the remoteIv column to attachments.
|
||||
*/
|
||||
object V244_AttachmentRemoteIv : SignalDatabaseMigration {
|
||||
override fun migrate(context: Application, db: SQLiteDatabase, oldVersion: Int, newVersion: Int) {
|
||||
db.execSQL("ALTER TABLE attachment ADD COLUMN remote_iv BLOB DEFAULT NULL;")
|
||||
}
|
||||
}
|
||||
@@ -8,11 +8,9 @@ package org.thoughtcrime.securesms.jobs
|
||||
import org.greenrobot.eventbus.EventBus
|
||||
import org.signal.core.util.logging.Log
|
||||
import org.signal.protos.resumableuploads.ResumableUpload
|
||||
import org.thoughtcrime.securesms.attachments.Attachment
|
||||
import org.thoughtcrime.securesms.attachments.AttachmentId
|
||||
import org.thoughtcrime.securesms.attachments.AttachmentUploadUtil
|
||||
import org.thoughtcrime.securesms.attachments.DatabaseAttachment
|
||||
import org.thoughtcrime.securesms.attachments.PointerAttachment
|
||||
import org.thoughtcrime.securesms.backup.v2.BackupRepository
|
||||
import org.thoughtcrime.securesms.backup.v2.BackupV2Event
|
||||
import org.thoughtcrime.securesms.database.AttachmentTable
|
||||
@@ -24,9 +22,8 @@ import org.thoughtcrime.securesms.jobs.protos.ArchiveAttachmentBackfillJobData
|
||||
import org.whispersystems.signalservice.api.NetworkResult
|
||||
import org.whispersystems.signalservice.api.archive.ArchiveMediaResponse
|
||||
import org.whispersystems.signalservice.api.archive.ArchiveMediaUploadFormStatusCodes
|
||||
import org.whispersystems.signalservice.api.messages.SignalServiceAttachmentPointer
|
||||
import org.whispersystems.signalservice.api.attachment.AttachmentUploadResult
|
||||
import java.io.IOException
|
||||
import java.util.Optional
|
||||
import kotlin.time.Duration.Companion.days
|
||||
|
||||
/**
|
||||
@@ -159,16 +156,16 @@ class ArchiveAttachmentBackfillJob private constructor(
|
||||
}
|
||||
|
||||
Log.d(TAG, "Beginning upload...")
|
||||
val remoteAttachment: SignalServiceAttachmentPointer = try {
|
||||
AppDependencies.signalServiceMessageSender.uploadAttachment(attachmentStream)
|
||||
} catch (e: IOException) {
|
||||
Log.w(TAG, "Failed to upload $attachmentId", e)
|
||||
return Result.retry(defaultBackoff())
|
||||
val attachmentApi = AppDependencies.signalServiceMessageSender.attachmentApi
|
||||
val uploadResult: AttachmentUploadResult = when (val result = attachmentApi.uploadAttachmentV4(attachmentStream)) {
|
||||
is NetworkResult.Success -> result.result
|
||||
is NetworkResult.ApplicationError -> throw result.throwable
|
||||
is NetworkResult.NetworkError -> return Result.retry(defaultBackoff())
|
||||
is NetworkResult.StatusCodeError -> return Result.retry(defaultBackoff())
|
||||
}
|
||||
Log.d(TAG, "Upload complete!")
|
||||
|
||||
val pointerAttachment: Attachment = PointerAttachment.forPointer(Optional.of(remoteAttachment), null, attachmentRecord.fastPreflightId).get()
|
||||
SignalDatabase.attachments.finalizeAttachmentAfterUpload(attachmentRecord.attachmentId, pointerAttachment, remoteAttachment.uploadTimestamp)
|
||||
SignalDatabase.attachments.finalizeAttachmentAfterUpload(attachmentRecord.attachmentId, uploadResult)
|
||||
SignalDatabase.attachments.setArchiveTransferState(attachmentRecord.attachmentId, AttachmentTable.ArchiveTransferState.BACKFILL_UPLOADED)
|
||||
|
||||
attachmentRecord = SignalDatabase.attachments.getAttachment(attachmentRecord.attachmentId)
|
||||
|
||||
@@ -7,6 +7,7 @@ package org.thoughtcrime.securesms.jobs
|
||||
import android.text.TextUtils
|
||||
import okhttp3.internal.http2.StreamResetException
|
||||
import org.greenrobot.eventbus.EventBus
|
||||
import org.signal.core.util.Base64
|
||||
import org.signal.core.util.concurrent.SignalExecutors
|
||||
import org.signal.core.util.inRoundedDays
|
||||
import org.signal.core.util.logging.Log
|
||||
@@ -17,7 +18,6 @@ import org.thoughtcrime.securesms.attachments.Attachment
|
||||
import org.thoughtcrime.securesms.attachments.AttachmentId
|
||||
import org.thoughtcrime.securesms.attachments.AttachmentUploadUtil
|
||||
import org.thoughtcrime.securesms.attachments.DatabaseAttachment
|
||||
import org.thoughtcrime.securesms.attachments.PointerAttachment
|
||||
import org.thoughtcrime.securesms.database.AttachmentTable
|
||||
import org.thoughtcrime.securesms.database.SignalDatabase
|
||||
import org.thoughtcrime.securesms.dependencies.AppDependencies
|
||||
@@ -32,6 +32,7 @@ import org.thoughtcrime.securesms.net.NotPushRegisteredException
|
||||
import org.thoughtcrime.securesms.recipients.Recipient
|
||||
import org.thoughtcrime.securesms.service.AttachmentProgressService
|
||||
import org.thoughtcrime.securesms.util.RemoteConfig
|
||||
import org.whispersystems.signalservice.api.attachment.AttachmentUploadResult
|
||||
import org.whispersystems.signalservice.api.crypto.AttachmentCipherStreamUtil
|
||||
import org.whispersystems.signalservice.api.messages.SignalServiceAttachment
|
||||
import org.whispersystems.signalservice.api.messages.SignalServiceAttachmentStream
|
||||
@@ -39,7 +40,6 @@ import org.whispersystems.signalservice.api.push.exceptions.NonSuccessfulResumab
|
||||
import org.whispersystems.signalservice.api.push.exceptions.ResumeLocationInvalidException
|
||||
import org.whispersystems.signalservice.internal.crypto.PaddingInputStream
|
||||
import java.io.IOException
|
||||
import java.util.Optional
|
||||
import java.util.concurrent.TimeUnit
|
||||
import kotlin.time.Duration.Companion.days
|
||||
import kotlin.time.Duration.Companion.milliseconds
|
||||
@@ -136,7 +136,10 @@ class AttachmentUploadJob private constructor(
|
||||
throw NotPushRegisteredException()
|
||||
}
|
||||
|
||||
SignalDatabase.attachments.createKeyIvIfNecessary(attachmentId)
|
||||
|
||||
val messageSender = AppDependencies.signalServiceMessageSender
|
||||
val attachmentApi = messageSender.attachmentApi
|
||||
val databaseAttachment = SignalDatabase.attachments.getAttachment(attachmentId) ?: throw InvalidAttachmentException("Cannot find the specified attachment.")
|
||||
|
||||
val timeSinceUpload = System.currentTimeMillis() - databaseAttachment.uploadTimestamp
|
||||
@@ -154,7 +157,17 @@ class AttachmentUploadJob private constructor(
|
||||
|
||||
if (uploadSpec == null) {
|
||||
Log.d(TAG, "Need an upload spec. Fetching...")
|
||||
uploadSpec = AppDependencies.signalServiceMessageSender.getResumableUploadSpec().toProto()
|
||||
uploadSpec = attachmentApi
|
||||
.getAttachmentV4UploadForm()
|
||||
.then { form ->
|
||||
attachmentApi.getResumableUploadSpec(
|
||||
key = Base64.decode(databaseAttachment.remoteKey!!),
|
||||
iv = databaseAttachment.remoteIv!!,
|
||||
uploadForm = form
|
||||
)
|
||||
}
|
||||
.successOrThrow()
|
||||
.toProto()
|
||||
} else {
|
||||
Log.d(TAG, "Re-using existing upload spec.")
|
||||
}
|
||||
@@ -163,9 +176,8 @@ class AttachmentUploadJob private constructor(
|
||||
try {
|
||||
getAttachmentNotificationIfNeeded(databaseAttachment).use { notification ->
|
||||
buildAttachmentStream(databaseAttachment, notification, uploadSpec!!).use { localAttachment ->
|
||||
val remoteAttachment = messageSender.uploadAttachment(localAttachment)
|
||||
val attachment = PointerAttachment.forPointer(Optional.of(remoteAttachment), null, databaseAttachment.fastPreflightId).get()
|
||||
SignalDatabase.attachments.finalizeAttachmentAfterUpload(databaseAttachment.attachmentId, attachment, remoteAttachment.uploadTimestamp)
|
||||
val uploadResult: AttachmentUploadResult = attachmentApi.uploadAttachmentV4(localAttachment).successOrThrow()
|
||||
SignalDatabase.attachments.finalizeAttachmentAfterUpload(databaseAttachment.attachmentId, uploadResult)
|
||||
ArchiveThumbnailUploadJob.enqueueIfNecessary(databaseAttachment.attachmentId)
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user