mirror of
https://github.com/signalapp/Signal-Android.git
synced 2026-04-21 09:20:19 +01:00
Add support for AttachmentBackfill sync messages.
This commit is contained in:
@@ -47,6 +47,9 @@ import org.thoughtcrime.securesms.groups.BadGroupIdException
|
||||
import org.thoughtcrime.securesms.groups.GroupChangeBusyException
|
||||
import org.thoughtcrime.securesms.groups.GroupId
|
||||
import org.thoughtcrime.securesms.jobs.AttachmentDownloadJob
|
||||
import org.thoughtcrime.securesms.jobs.AttachmentUploadJob
|
||||
import org.thoughtcrime.securesms.jobs.MultiDeviceAttachmentBackfillMissingJob
|
||||
import org.thoughtcrime.securesms.jobs.MultiDeviceAttachmentBackfillUpdateJob
|
||||
import org.thoughtcrime.securesms.jobs.MultiDeviceBlockedUpdateJob
|
||||
import org.thoughtcrime.securesms.jobs.MultiDeviceConfigurationUpdateJob
|
||||
import org.thoughtcrime.securesms.jobs.MultiDeviceContactSyncJob
|
||||
@@ -95,6 +98,7 @@ import org.thoughtcrime.securesms.util.EarlyMessageCacheEntry
|
||||
import org.thoughtcrime.securesms.util.IdentityUtil
|
||||
import org.thoughtcrime.securesms.util.MediaUtil
|
||||
import org.thoughtcrime.securesms.util.MessageConstraintsUtil
|
||||
import org.thoughtcrime.securesms.util.RemoteConfig
|
||||
import org.thoughtcrime.securesms.util.TextSecurePreferences
|
||||
import org.thoughtcrime.securesms.util.Util
|
||||
import org.whispersystems.signalservice.api.crypto.EnvelopeMetadata
|
||||
@@ -106,7 +110,9 @@ import org.whispersystems.signalservice.api.push.ServiceId.PNI
|
||||
import org.whispersystems.signalservice.api.push.SignalServiceAddress
|
||||
import org.whispersystems.signalservice.api.storage.StorageKey
|
||||
import org.whispersystems.signalservice.api.util.UuidUtil
|
||||
import org.whispersystems.signalservice.internal.push.AddressableMessage
|
||||
import org.whispersystems.signalservice.internal.push.Content
|
||||
import org.whispersystems.signalservice.internal.push.ConversationIdentifier
|
||||
import org.whispersystems.signalservice.internal.push.DataMessage
|
||||
import org.whispersystems.signalservice.internal.push.EditMessage
|
||||
import org.whispersystems.signalservice.internal.push.Envelope
|
||||
@@ -129,6 +135,7 @@ import java.util.Optional
|
||||
import java.util.UUID
|
||||
import java.util.concurrent.TimeUnit
|
||||
import kotlin.time.Duration
|
||||
import kotlin.time.Duration.Companion.days
|
||||
import kotlin.time.Duration.Companion.seconds
|
||||
|
||||
object SyncMessageProcessor {
|
||||
@@ -162,6 +169,8 @@ object SyncMessageProcessor {
|
||||
syncMessage.callLinkUpdate != null -> handleSynchronizeCallLink(syncMessage.callLinkUpdate!!, envelope.timestamp!!)
|
||||
syncMessage.callLogEvent != null -> handleSynchronizeCallLogEvent(syncMessage.callLogEvent!!, envelope.timestamp!!)
|
||||
syncMessage.deleteForMe != null -> handleSynchronizeDeleteForMe(context, syncMessage.deleteForMe!!, envelope.timestamp!!, earlyMessageCacheEntry)
|
||||
syncMessage.attachmentBackfillRequest != null -> handleSynchronizeAttachmentBackfillRequest(syncMessage.attachmentBackfillRequest!!, envelope.timestamp!!)
|
||||
syncMessage.attachmentBackfillResponse != null -> warn(envelope.timestamp!!, "Contains a backfill response, but we don't handle these!")
|
||||
else -> warn(envelope.timestamp!!, "Contains no known sync types...")
|
||||
}
|
||||
}
|
||||
@@ -1634,7 +1643,70 @@ object SyncMessageProcessor {
|
||||
}
|
||||
}
|
||||
|
||||
private fun SyncMessage.DeleteForMe.ConversationIdentifier.toRecipientId(): RecipientId? {
|
||||
private fun handleSynchronizeAttachmentBackfillRequest(request: SyncMessage.AttachmentBackfillRequest, timestamp: Long) {
|
||||
if (!RemoteConfig.attachmentBackfillSync) {
|
||||
warn(timestamp, "[AttachmentBackfillRequest] Remote config not enabled! Skipping.")
|
||||
return
|
||||
}
|
||||
|
||||
if (request.targetMessage == null || request.targetConversation == null) {
|
||||
warn(timestamp, "[AttachmentBackfillRequest] Target message or target conversation was unset! Can't formulate a response, ignoring.")
|
||||
return
|
||||
}
|
||||
|
||||
val syncMessageId = request.targetMessage!!.toSyncMessageId(timestamp)
|
||||
if (syncMessageId == null) {
|
||||
warn(timestamp, "[AttachmentBackfillRequest] Invalid targetMessageId! Can't formulate a response, ignoring.")
|
||||
MultiDeviceAttachmentBackfillMissingJob.enqueue(request.targetMessage!!, request.targetConversation!!)
|
||||
return
|
||||
}
|
||||
|
||||
val conversationRecipientId: RecipientId? = request.targetConversation!!.toRecipientId()
|
||||
if (conversationRecipientId == null) {
|
||||
warn(timestamp, "[AttachmentBackfillRequest] Failed to find the target conversation! Enqueuing a 'missing' response.")
|
||||
MultiDeviceAttachmentBackfillMissingJob.enqueue(request.targetMessage!!, request.targetConversation!!)
|
||||
return
|
||||
}
|
||||
|
||||
val threadId = SignalDatabase.threads.getThreadIdFor(conversationRecipientId)
|
||||
if (threadId == null) {
|
||||
warn(timestamp, "[AttachmentBackfillRequest] No thread exists for the conversation! Enqueuing a 'missing' response.")
|
||||
MultiDeviceAttachmentBackfillMissingJob.enqueue(request.targetMessage!!, request.targetConversation!!)
|
||||
return
|
||||
}
|
||||
|
||||
val messageId: Long? = SignalDatabase.messages.getMessageIdOrNull(syncMessageId, threadId)
|
||||
if (messageId == null) {
|
||||
warn(timestamp, "[AttachmentBackfillRequest] Unable to find message! Enqueuing a 'missing' response.")
|
||||
MultiDeviceAttachmentBackfillMissingJob.enqueue(request.targetMessage!!, request.targetConversation!!)
|
||||
return
|
||||
}
|
||||
|
||||
val attachments: List<DatabaseAttachment> = SignalDatabase.attachments.getAttachmentsForMessage(messageId).sortedBy { it.displayOrder }
|
||||
if (attachments.isEmpty()) {
|
||||
warn(timestamp, "[AttachmentBackfillRequest] There were no attachments found for the message! Enqueuing a 'missing' response.")
|
||||
MultiDeviceAttachmentBackfillMissingJob.enqueue(request.targetMessage!!, request.targetConversation!!)
|
||||
return
|
||||
}
|
||||
|
||||
val now = System.currentTimeMillis()
|
||||
val needsUpload = attachments.filter { now - it.uploadTimestamp > 3.days.inWholeMilliseconds }
|
||||
log(timestamp, "[AttachmentBackfillRequest] ${needsUpload.size}/${attachments.size} attachments need to be re-uploaded.")
|
||||
|
||||
for (attachment in needsUpload) {
|
||||
AppDependencies.jobManager
|
||||
.startChain(AttachmentUploadJob(attachment.attachmentId))
|
||||
.then(MultiDeviceAttachmentBackfillUpdateJob(request.targetMessage!!, request.targetConversation!!, messageId))
|
||||
.enqueue()
|
||||
}
|
||||
|
||||
if (needsUpload.size != attachments.size) {
|
||||
log(timestamp, "[AttachmentBackfillRequest] At least one attachment didn't need to be uploaded. Enqueuing update job immediately.")
|
||||
MultiDeviceAttachmentBackfillUpdateJob.enqueue(request.targetMessage!!, request.targetConversation!!, messageId)
|
||||
}
|
||||
}
|
||||
|
||||
private fun ConversationIdentifier.toRecipientId(): RecipientId? {
|
||||
return when {
|
||||
threadGroupId != null -> {
|
||||
try {
|
||||
@@ -1659,7 +1731,7 @@ object SyncMessageProcessor {
|
||||
}
|
||||
}
|
||||
|
||||
private fun SyncMessage.DeleteForMe.AddressableMessage.toSyncMessageId(envelopeTimestamp: Long): MessageTable.SyncMessageId? {
|
||||
private fun AddressableMessage.toSyncMessageId(envelopeTimestamp: Long): MessageTable.SyncMessageId? {
|
||||
return if (this.sentTimestamp != null && (this.authorServiceId != null || this.authorE164 != null)) {
|
||||
val serviceId = ServiceId.parseOrNull(this.authorServiceId)
|
||||
val id = if (serviceId != null) {
|
||||
|
||||
Reference in New Issue
Block a user