mirror of
https://github.com/signalapp/Signal-Android.git
synced 2025-12-23 20:48:43 +00:00
Do not generate archive thumbnails for quotes.
This commit is contained in:
@@ -51,6 +51,30 @@ class BackupMediaSnapshotTableTest {
|
||||
assertThat(count).isEqualTo(countWithThumbnails)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun givenAnEmptyTable_whenIWriteToTableAndCommitQuotes_thenIExpectFilledTableWithNoThumbnails() {
|
||||
val inputCount = 100
|
||||
|
||||
SignalDatabase.backupMediaSnapshots.writePendingMediaObjects(generateArchiveMediaItemSequence(count = inputCount, quote = true))
|
||||
SignalDatabase.backupMediaSnapshots.commitPendingRows()
|
||||
|
||||
val count = getCountForLatestSnapshot(includeThumbnails = true)
|
||||
|
||||
assertThat(count).isEqualTo(inputCount)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun givenAnEmptyTable_whenIWriteToTableAndCommitNonMedia_thenIExpectFilledTableWithNoThumbnails() {
|
||||
val inputCount = 100
|
||||
|
||||
SignalDatabase.backupMediaSnapshots.writePendingMediaObjects(generateArchiveMediaItemSequence(count = inputCount, contentType = "text/plain"))
|
||||
SignalDatabase.backupMediaSnapshots.commitPendingRows()
|
||||
|
||||
val count = getCountForLatestSnapshot(includeThumbnails = true)
|
||||
|
||||
assertThat(count).isEqualTo(inputCount)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun givenAFilledTable_whenIReinsertObjects_thenIExpectUncommittedOverrides() {
|
||||
val initialCount = 100
|
||||
@@ -290,19 +314,21 @@ class BackupMediaSnapshotTableTest {
|
||||
.readToSingleInt(0)
|
||||
}
|
||||
|
||||
private fun generateArchiveMediaItemSequence(count: Int): Sequence<ArchiveMediaItem> {
|
||||
private fun generateArchiveMediaItemSequence(count: Int, quote: Boolean = false, contentType: String = "image/jpeg"): Sequence<ArchiveMediaItem> {
|
||||
return (1..count)
|
||||
.asSequence()
|
||||
.map { createArchiveMediaItem(it) }
|
||||
.map { createArchiveMediaItem(it, quote = quote, contentType = contentType) }
|
||||
}
|
||||
|
||||
private fun createArchiveMediaItem(seed: Int, cdn: Int = 0): ArchiveMediaItem {
|
||||
private fun createArchiveMediaItem(seed: Int, cdn: Int = 0, quote: Boolean = false, contentType: String = "image/jpeg"): ArchiveMediaItem {
|
||||
return ArchiveMediaItem(
|
||||
mediaId = "media_id_$seed",
|
||||
thumbnailMediaId = "thumbnail_media_id_$seed",
|
||||
cdn = cdn,
|
||||
plaintextHash = Util.toByteArray(seed),
|
||||
remoteKey = Util.toByteArray(seed)
|
||||
remoteKey = Util.toByteArray(seed),
|
||||
quote = quote,
|
||||
contentType = contentType
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
@@ -41,8 +41,10 @@ import org.signal.core.util.getForeignKeyViolations
|
||||
import org.signal.core.util.logging.Log
|
||||
import org.signal.core.util.logging.logW
|
||||
import org.signal.core.util.money.FiatMoney
|
||||
import org.signal.core.util.requireBoolean
|
||||
import org.signal.core.util.requireIntOrNull
|
||||
import org.signal.core.util.requireNonNullString
|
||||
import org.signal.core.util.requireString
|
||||
import org.signal.core.util.stream.NonClosingOutputStream
|
||||
import org.signal.core.util.urlEncode
|
||||
import org.signal.core.util.withinTransaction
|
||||
@@ -2393,11 +2395,22 @@ class ArchiveMediaItemIterator(private val cursor: Cursor) : Iterator<ArchiveMed
|
||||
val plaintextHash = cursor.requireNonNullString(AttachmentTable.DATA_HASH_END).decodeBase64OrThrow()
|
||||
val remoteKey = cursor.requireNonNullString(AttachmentTable.REMOTE_KEY).decodeBase64OrThrow()
|
||||
val cdn = cursor.requireIntOrNull(AttachmentTable.ARCHIVE_CDN)
|
||||
val quote = cursor.requireBoolean(AttachmentTable.QUOTE)
|
||||
val contentType = cursor.requireString(AttachmentTable.CONTENT_TYPE)
|
||||
|
||||
val mediaId = MediaName.fromPlaintextHashAndRemoteKey(plaintextHash, remoteKey).toMediaId(SignalStore.backup.mediaRootBackupKey).encode()
|
||||
val thumbnailMediaId = MediaName.fromPlaintextHashAndRemoteKeyForThumbnail(plaintextHash, remoteKey).toMediaId(SignalStore.backup.mediaRootBackupKey).encode()
|
||||
|
||||
cursor.moveToNext()
|
||||
return ArchiveMediaItem(mediaId, thumbnailMediaId, cdn, plaintextHash, remoteKey)
|
||||
|
||||
return ArchiveMediaItem(
|
||||
mediaId = mediaId,
|
||||
thumbnailMediaId = thumbnailMediaId,
|
||||
cdn = cdn,
|
||||
plaintextHash = plaintextHash,
|
||||
remoteKey = remoteKey,
|
||||
quote = quote,
|
||||
contentType = contentType
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -416,7 +416,7 @@ class AttachmentTable(
|
||||
*/
|
||||
fun getAttachmentsEligibleForArchiveUpload(): Cursor {
|
||||
return readableDatabase
|
||||
.select(DATA_HASH_END, REMOTE_KEY, ARCHIVE_CDN)
|
||||
.select(DATA_HASH_END, REMOTE_KEY, ARCHIVE_CDN, QUOTE, CONTENT_TYPE)
|
||||
.from(TABLE_NAME)
|
||||
.where("$DATA_HASH_END NOT NULL AND $REMOTE_KEY NOT NULL AND $ARCHIVE_TRANSFER_STATE != ${ArchiveTransferState.PERMANENT_FAILURE.value}")
|
||||
.run()
|
||||
|
||||
@@ -24,6 +24,7 @@ import org.signal.core.util.toInt
|
||||
import org.signal.core.util.update
|
||||
import org.signal.core.util.withinTransaction
|
||||
import org.thoughtcrime.securesms.backup.v2.ArchivedMediaObject
|
||||
import org.thoughtcrime.securesms.util.MediaUtil
|
||||
|
||||
/**
|
||||
* When we delete attachments locally, we can't immediately delete them from the archive CDN. This is because there is still a backup that exists that
|
||||
@@ -140,7 +141,10 @@ class BackupMediaSnapshotTable(context: Context, database: SignalDatabase) : Dat
|
||||
)
|
||||
|
||||
writePendingMediaObjectsChunk(
|
||||
chunk.map { MediaEntry(it.thumbnailMediaId, it.cdn, it.plaintextHash, it.remoteKey, isThumbnail = true) }
|
||||
chunk
|
||||
.filterNot { it.quote }
|
||||
.filter { MediaUtil.isImageOrVideoType(it.contentType) }
|
||||
.map { MediaEntry(it.thumbnailMediaId, it.cdn, it.plaintextHash, it.remoteKey, isThumbnail = true) }
|
||||
)
|
||||
}
|
||||
}
|
||||
@@ -291,6 +295,10 @@ class BackupMediaSnapshotTable(context: Context, database: SignalDatabase) : Dat
|
||||
}
|
||||
|
||||
private fun writePendingMediaObjectsChunk(chunk: List<MediaEntry>) {
|
||||
if (chunk.isEmpty()) {
|
||||
return
|
||||
}
|
||||
|
||||
val values = chunk.map {
|
||||
contentValuesOf(
|
||||
MEDIA_ID to it.mediaId,
|
||||
@@ -324,7 +332,9 @@ class BackupMediaSnapshotTable(context: Context, database: SignalDatabase) : Dat
|
||||
val thumbnailMediaId: String,
|
||||
val cdn: Int?,
|
||||
val plaintextHash: ByteArray,
|
||||
val remoteKey: ByteArray
|
||||
val remoteKey: ByteArray,
|
||||
val quote: Boolean,
|
||||
val contentType: String?
|
||||
)
|
||||
|
||||
class CdnMismatchResult(
|
||||
|
||||
@@ -98,6 +98,11 @@ class ArchiveThumbnailUploadJob private constructor(
|
||||
return Result.success()
|
||||
}
|
||||
|
||||
if (attachment.quote) {
|
||||
Log.w(TAG, "$attachmentId is a quote, skipping.")
|
||||
return Result.success()
|
||||
}
|
||||
|
||||
if (attachment.remoteDigest == null && attachment.dataHash == null && attachment.hadIntegrityCheckPerformed()) {
|
||||
Log.w(TAG, "$attachmentId has no integrity check! Cannot proceed.")
|
||||
return Result.success()
|
||||
|
||||
@@ -366,7 +366,7 @@ class BackupMessagesJob private constructor(
|
||||
cancellationSignal = { this.isCanceled },
|
||||
currentTime = currentTime
|
||||
) {
|
||||
writeMediaCursorToTemporaryTable(it, currentTime = currentTime, mediaBackupEnabled = SignalStore.backup.backsUpMedia)
|
||||
writeMediaCursorToTemporaryTable(it, mediaBackupEnabled = SignalStore.backup.backsUpMedia)
|
||||
}
|
||||
|
||||
if (isCanceled) {
|
||||
@@ -415,7 +415,7 @@ class BackupMessagesJob private constructor(
|
||||
)
|
||||
}
|
||||
|
||||
private fun writeMediaCursorToTemporaryTable(db: SignalDatabase, mediaBackupEnabled: Boolean, currentTime: Long) {
|
||||
private fun writeMediaCursorToTemporaryTable(db: SignalDatabase, mediaBackupEnabled: Boolean) {
|
||||
if (mediaBackupEnabled) {
|
||||
db.attachmentTable.getAttachmentsEligibleForArchiveUpload().use {
|
||||
SignalDatabase.backupMediaSnapshots.writePendingMediaObjects(
|
||||
|
||||
@@ -192,7 +192,7 @@ class CopyAttachmentToArchiveJob private constructor(private val attachmentId: A
|
||||
Log.d(TAG, "[$attachmentId] Updating archive transfer state to ${AttachmentTable.ArchiveTransferState.FINISHED}")
|
||||
SignalDatabase.attachments.setArchiveTransferState(attachmentId, AttachmentTable.ArchiveTransferState.FINISHED)
|
||||
|
||||
if (!isCanceled) {
|
||||
if (!isCanceled && !attachment.quote) {
|
||||
ArchiveThumbnailUploadJob.enqueueIfNecessary(attachmentId)
|
||||
} else {
|
||||
Log.d(TAG, "[$attachmentId] Refusing to enqueue thumb for canceled upload.")
|
||||
|
||||
Reference in New Issue
Block a user