Add view-once support to backupsV2.

This commit is contained in:
Greyson Parrelli
2024-10-03 16:42:57 -04:00
parent 97ce7e4150
commit 5efa1be3a5
20 changed files with 49 additions and 4 deletions

View File

@@ -182,6 +182,11 @@ class ArchiveImportExportTests {
runTests { it.startsWith("chat_item_thread_merge_update_") } runTests { it.startsWith("chat_item_thread_merge_update_") }
} }
@Test
fun chatItemViewOnce() {
runTests { it.startsWith("chat_item_view_once_") }
}
// @Test // @Test
fun recipientCallLink() { fun recipientCallLink() {
runTests { it.startsWith("recipient_call_link_") } runTests { it.startsWith("recipient_call_link_") }

View File

@@ -52,7 +52,8 @@ fun MessageTable.getMessagesForBackup(db: SignalDatabase, backupTime: Long, medi
MessageTable.NETWORK_FAILURES, MessageTable.NETWORK_FAILURES,
MessageTable.MISMATCHED_IDENTITIES, MessageTable.MISMATCHED_IDENTITIES,
"${MessageTable.TYPE} & ${MessageTypes.BASE_TYPE_MASK} AS $COLUMN_BASE_TYPE", "${MessageTable.TYPE} & ${MessageTypes.BASE_TYPE_MASK} AS $COLUMN_BASE_TYPE",
MessageTable.MESSAGE_EXTRAS MessageTable.MESSAGE_EXTRAS,
MessageTable.VIEW_ONCE
) )
.from(MessageTable.TABLE_NAME) .from(MessageTable.TABLE_NAME)
.where( .where(

View File

@@ -44,6 +44,7 @@ import org.thoughtcrime.securesms.backup.v2.proto.Sticker
import org.thoughtcrime.securesms.backup.v2.proto.StickerMessage import org.thoughtcrime.securesms.backup.v2.proto.StickerMessage
import org.thoughtcrime.securesms.backup.v2.proto.Text import org.thoughtcrime.securesms.backup.v2.proto.Text
import org.thoughtcrime.securesms.backup.v2.proto.ThreadMergeChatUpdate import org.thoughtcrime.securesms.backup.v2.proto.ThreadMergeChatUpdate
import org.thoughtcrime.securesms.backup.v2.proto.ViewOnceMessage
import org.thoughtcrime.securesms.backup.v2.util.toRemoteFilePointer import org.thoughtcrime.securesms.backup.v2.util.toRemoteFilePointer
import org.thoughtcrime.securesms.contactshare.Contact import org.thoughtcrime.securesms.contactshare.Contact
import org.thoughtcrime.securesms.database.AttachmentTable import org.thoughtcrime.securesms.database.AttachmentTable
@@ -245,6 +246,10 @@ class ChatItemArchiveExporter(
builder.contactMessage = record.toRemoteContactMessage(mediaArchiveEnabled = mediaArchiveEnabled, reactionRecords = reactionsById[id], attachments = attachmentsById[id]) builder.contactMessage = record.toRemoteContactMessage(mediaArchiveEnabled = mediaArchiveEnabled, reactionRecords = reactionsById[id], attachments = attachmentsById[id])
} }
record.viewOnce -> {
builder.viewOnceMessage = record.toRemoteViewOnceMessage(mediaArchiveEnabled = mediaArchiveEnabled, reactionRecords = reactionsById[id], attachments = attachmentsById[id])
}
else -> { else -> {
if (record.body == null && !attachmentsById.containsKey(record.id)) { if (record.body == null && !attachmentsById.containsKey(record.id)) {
Log.w(TAG, "Record with ID ${record.id} missing a body and doesn't have attachments. Skipping.") Log.w(TAG, "Record with ID ${record.id} missing a body and doesn't have attachments. Skipping.")
@@ -556,6 +561,15 @@ private fun LinkPreview.toRemoteLinkPreview(mediaArchiveEnabled: Boolean): org.t
) )
} }
private fun BackupMessageRecord.toRemoteViewOnceMessage(mediaArchiveEnabled: Boolean, reactionRecords: List<ReactionRecord>?, attachments: List<DatabaseAttachment>?): ViewOnceMessage {
val attachment: DatabaseAttachment? = attachments?.firstOrNull()
return ViewOnceMessage(
attachment = attachment?.toRemoteMessageAttachment(mediaArchiveEnabled),
reactions = reactionRecords?.toRemote() ?: emptyList()
)
}
private fun BackupMessageRecord.toRemoteContactMessage(mediaArchiveEnabled: Boolean, reactionRecords: List<ReactionRecord>?, attachments: List<DatabaseAttachment>?): ContactMessage { private fun BackupMessageRecord.toRemoteContactMessage(mediaArchiveEnabled: Boolean, reactionRecords: List<ReactionRecord>?, attachments: List<DatabaseAttachment>?): ContactMessage {
val sharedContacts = toRemoteSharedContacts(attachments) val sharedContacts = toRemoteSharedContacts(attachments)
@@ -1082,7 +1096,8 @@ private fun Cursor.toBackupMessageRecord(): BackupMessageRecord {
networkFailureRecipientIds = this.requireString(MessageTable.NETWORK_FAILURES).parseNetworkFailures(), networkFailureRecipientIds = this.requireString(MessageTable.NETWORK_FAILURES).parseNetworkFailures(),
identityMismatchRecipientIds = this.requireString(MessageTable.MISMATCHED_IDENTITIES).parseIdentityMismatches(), identityMismatchRecipientIds = this.requireString(MessageTable.MISMATCHED_IDENTITIES).parseIdentityMismatches(),
baseType = this.requireLong(COLUMN_BASE_TYPE), baseType = this.requireLong(COLUMN_BASE_TYPE),
messageExtras = this.requireBlob(MessageTable.MESSAGE_EXTRAS).parseMessageExtras() messageExtras = this.requireBlob(MessageTable.MESSAGE_EXTRAS).parseMessageExtras(),
viewOnce = this.requireBoolean(MessageTable.VIEW_ONCE)
) )
} }
@@ -1119,5 +1134,6 @@ private class BackupMessageRecord(
val networkFailureRecipientIds: Set<Long>, val networkFailureRecipientIds: Set<Long>,
val identityMismatchRecipientIds: Set<Long>, val identityMismatchRecipientIds: Set<Long>,
val baseType: Long, val baseType: Long,
val messageExtras: MessageExtras? val messageExtras: MessageExtras?,
val viewOnce: Boolean
) )

View File

@@ -34,6 +34,7 @@ import org.thoughtcrime.securesms.backup.v2.proto.SendStatus
import org.thoughtcrime.securesms.backup.v2.proto.SimpleChatUpdate import org.thoughtcrime.securesms.backup.v2.proto.SimpleChatUpdate
import org.thoughtcrime.securesms.backup.v2.proto.StandardMessage import org.thoughtcrime.securesms.backup.v2.proto.StandardMessage
import org.thoughtcrime.securesms.backup.v2.proto.Sticker import org.thoughtcrime.securesms.backup.v2.proto.Sticker
import org.thoughtcrime.securesms.backup.v2.proto.ViewOnceMessage
import org.thoughtcrime.securesms.backup.v2.util.toLocalAttachment import org.thoughtcrime.securesms.backup.v2.util.toLocalAttachment
import org.thoughtcrime.securesms.contactshare.Contact import org.thoughtcrime.securesms.contactshare.Contact
import org.thoughtcrime.securesms.database.CallTable import org.thoughtcrime.securesms.database.CallTable
@@ -429,6 +430,15 @@ class ChatItemArchiveImporter(
} }
} }
if (this.viewOnceMessage != null) {
val attachment = this.viewOnceMessage.attachment?.toLocalAttachment()
if (attachment != null) {
followUp = { messageRowId ->
SignalDatabase.attachments.insertAttachmentsForMessage(messageRowId, listOf(attachment), emptyList())
}
}
}
return MessageInsert(contentValues, followUp) return MessageInsert(contentValues, followUp)
} }
@@ -484,6 +494,7 @@ class ChatItemArchiveImporter(
this.updateMessage != null -> contentValues.addUpdateMessage(this.updateMessage) this.updateMessage != null -> contentValues.addUpdateMessage(this.updateMessage)
this.paymentNotification != null -> contentValues.addPaymentNotification(this, chatRecipientId) this.paymentNotification != null -> contentValues.addPaymentNotification(this, chatRecipientId)
this.giftBadge != null -> contentValues.addGiftBadge(this.giftBadge) this.giftBadge != null -> contentValues.addGiftBadge(this.giftBadge)
this.viewOnceMessage != null -> contentValues.addViewOnce(this.viewOnceMessage)
} }
return contentValues return contentValues
@@ -526,6 +537,7 @@ class ChatItemArchiveImporter(
this.standardMessage != null -> this.standardMessage.reactions this.standardMessage != null -> this.standardMessage.reactions
this.contactMessage != null -> this.contactMessage.reactions this.contactMessage != null -> this.contactMessage.reactions
this.stickerMessage != null -> this.stickerMessage.reactions this.stickerMessage != null -> this.stickerMessage.reactions
this.viewOnceMessage != null -> this.viewOnceMessage.reactions
else -> emptyList() else -> emptyList()
} }
@@ -822,6 +834,10 @@ class ChatItemArchiveImporter(
put(MessageTable.BODY, Base64.encodeWithPadding(GiftBadge.ADAPTER.encode(dbGiftBadge))) put(MessageTable.BODY, Base64.encodeWithPadding(GiftBadge.ADAPTER.encode(dbGiftBadge)))
} }
private fun ContentValues.addViewOnce(viewOnce: ViewOnceMessage) {
put(MessageTable.VIEW_ONCE, true.toInt())
}
private fun String?.tryParseMoney(): Money? { private fun String?.tryParseMoney(): Money? {
if (this.isNullOrEmpty()) { if (this.isNullOrEmpty()) {
return null return null

View File

@@ -341,6 +341,7 @@ message ChatItem {
ChatUpdateMessage updateMessage = 15; ChatUpdateMessage updateMessage = 15;
PaymentNotification paymentNotification = 16; PaymentNotification paymentNotification = 16;
GiftBadge giftBadge = 17; GiftBadge giftBadge = 17;
ViewOnceMessage viewOnceMessage = 18;
} }
} }
@@ -469,6 +470,12 @@ message GiftBadge {
State state = 2; State state = 2;
} }
message ViewOnceMessage {
// Will be null for viewed messages
MessageAttachment attachment = 1;
repeated Reaction reactions = 2;
}
message ContactAttachment { message ContactAttachment {
message Name { message Name {
optional string givenName = 1; optional string givenName = 1;