Centralize media message inserts.

This commit is contained in:
Greyson Parrelli
2023-10-23 14:18:26 -04:00
parent 4b004f70ec
commit 4f754ae309
7 changed files with 81 additions and 120 deletions

View File

@@ -73,7 +73,7 @@ class ConversationItemPreviewer {
attachments = PointerAttachment.forPointers(Optional.of(attachments)) attachments = PointerAttachment.forPointers(Optional.of(attachments))
) )
SignalDatabase.messages.insertSecureDecryptedMessageInbox(message, SignalDatabase.threads.getOrCreateThreadIdFor(other)).get() SignalDatabase.messages.insertMessageInbox(message, SignalDatabase.threads.getOrCreateThreadIdFor(other)).get()
ThreadUtil.sleep(1) ThreadUtil.sleep(1)
} }
@@ -92,7 +92,7 @@ class ConversationItemPreviewer {
attachments = PointerAttachment.forPointers(Optional.of(attachments)) attachments = PointerAttachment.forPointers(Optional.of(attachments))
) )
val insert = SignalDatabase.messages.insertSecureDecryptedMessageInbox(message, SignalDatabase.threads.getOrCreateThreadIdFor(other)).get() val insert = SignalDatabase.messages.insertMessageInbox(message, SignalDatabase.threads.getOrCreateThreadIdFor(other)).get()
SignalDatabase.attachments.getAttachmentsForMessage(insert.messageId).forEachIndexed { index, attachment -> SignalDatabase.attachments.getAttachmentsForMessage(insert.messageId).forEachIndexed { index, attachment ->
// if (index != 1) { // if (index != 1) {

View File

@@ -58,6 +58,6 @@ object MmsHelper {
message: IncomingMediaMessage, message: IncomingMediaMessage,
threadId: Long threadId: Long
): Optional<MessageTable.InsertResult> { ): Optional<MessageTable.InsertResult> {
return SignalDatabase.messages.insertSecureDecryptedMessageInbox(message, threadId) return SignalDatabase.messages.insertMessageInbox(message, threadId)
} }
} }

View File

@@ -825,9 +825,9 @@ class RecipientTableTest_getAndPossiblyMerge {
val smsId2: Long = SignalDatabase.messages.insertMessageInbox(smsMessage(sender = recipientIdE164, time = 1, body = "1")).get().messageId val smsId2: Long = SignalDatabase.messages.insertMessageInbox(smsMessage(sender = recipientIdE164, time = 1, body = "1")).get().messageId
val smsId3: Long = SignalDatabase.messages.insertMessageInbox(smsMessage(sender = recipientIdAci, time = 2, body = "2")).get().messageId val smsId3: Long = SignalDatabase.messages.insertMessageInbox(smsMessage(sender = recipientIdAci, time = 2, body = "2")).get().messageId
val mmsId1: Long = SignalDatabase.messages.insertSecureDecryptedMessageInbox(mmsMessage(sender = recipientIdAci, time = 3, body = "3"), -1).get().messageId val mmsId1: Long = SignalDatabase.messages.insertMessageInbox(mmsMessage(sender = recipientIdAci, time = 3, body = "3"), -1).get().messageId
val mmsId2: Long = SignalDatabase.messages.insertSecureDecryptedMessageInbox(mmsMessage(sender = recipientIdE164, time = 4, body = "4"), -1).get().messageId val mmsId2: Long = SignalDatabase.messages.insertMessageInbox(mmsMessage(sender = recipientIdE164, time = 4, body = "4"), -1).get().messageId
val mmsId3: Long = SignalDatabase.messages.insertSecureDecryptedMessageInbox(mmsMessage(sender = recipientIdAci, time = 5, body = "5"), -1).get().messageId val mmsId3: Long = SignalDatabase.messages.insertMessageInbox(mmsMessage(sender = recipientIdAci, time = 5, body = "5"), -1).get().messageId
val threadIdAci: Long = SignalDatabase.threads.getThreadIdFor(recipientIdAci)!! val threadIdAci: Long = SignalDatabase.threads.getThreadIdFor(recipientIdAci)!!
val threadIdE164: Long = SignalDatabase.threads.getThreadIdFor(recipientIdE164)!! val threadIdE164: Long = SignalDatabase.threads.getThreadIdFor(recipientIdE164)!!

View File

@@ -1107,7 +1107,7 @@ open class MessageTable(context: Context?, databaseHelper: SignalDatabase) : Dat
} }
fun insertEditMessageInbox(threadId: Long, mediaMessage: IncomingMediaMessage, targetMessage: MediaMmsMessageRecord): Optional<InsertResult> { fun insertEditMessageInbox(threadId: Long, mediaMessage: IncomingMediaMessage, targetMessage: MediaMmsMessageRecord): Optional<InsertResult> {
val insertResult = insertSecureDecryptedMessageInbox(retrieved = mediaMessage, threadId = threadId, edittedMediaMessage = targetMessage, notifyObservers = false) val insertResult = insertMessageInbox(retrieved = mediaMessage, candidateThreadId = threadId, editedMessage = targetMessage, notifyObservers = false)
if (insertResult.isPresent) { if (insertResult.isPresent) {
val (messageId) = insertResult.get() val (messageId) = insertResult.get()
@@ -2583,32 +2583,30 @@ open class MessageTable(context: Context?, databaseHelper: SignalDatabase) : Dat
} ?: throw NoSuchMessageException("No record found for id: $messageId") } ?: throw NoSuchMessageException("No record found for id: $messageId")
} }
@JvmOverloads
@Throws(MmsException::class) @Throws(MmsException::class)
private fun insertMessageInbox( fun insertMessageInbox(
retrieved: IncomingMediaMessage, retrieved: IncomingMediaMessage,
contentLocation: String,
candidateThreadId: Long, candidateThreadId: Long,
mailbox: Long, editedMessage: MediaMmsMessageRecord? = null,
editedMessage: MediaMmsMessageRecord?, notifyObservers: Boolean = true
notifyObservers: Boolean
): Optional<InsertResult> { ): Optional<InsertResult> {
val type = retrieved.toMessageType()
val threadId = if (candidateThreadId == -1L || retrieved.isGroupMessage) { val threadId = if (candidateThreadId == -1L || retrieved.isGroupMessage) {
getThreadIdFor(retrieved) getThreadIdFor(retrieved)
} else { } else {
candidateThreadId candidateThreadId
} }
val silentUpdate = mailbox and MessageTypes.GROUP_UPDATE_BIT > 0
val contentValues = contentValuesOf( val contentValues = contentValuesOf(
DATE_SENT to retrieved.sentTimeMillis, DATE_SENT to retrieved.sentTimeMillis,
DATE_SERVER to retrieved.serverTimeMillis, DATE_SERVER to retrieved.serverTimeMillis,
FROM_RECIPIENT_ID to retrieved.from!!.serialize(), FROM_RECIPIENT_ID to retrieved.from!!.serialize(),
TO_RECIPIENT_ID to Recipient.self().id.serialize(), TO_RECIPIENT_ID to Recipient.self().id.serialize(),
TYPE to mailbox, TYPE to type,
MMS_MESSAGE_TYPE to PduHeaders.MESSAGE_TYPE_RETRIEVE_CONF, MMS_MESSAGE_TYPE to PduHeaders.MESSAGE_TYPE_RETRIEVE_CONF,
THREAD_ID to threadId, THREAD_ID to threadId,
MMS_CONTENT_LOCATION to contentLocation,
MMS_STATUS to MmsStatus.DOWNLOAD_INITIALIZED, MMS_STATUS to MmsStatus.DOWNLOAD_INITIALIZED,
DATE_RECEIVED to if (retrieved.isPushMessage) retrieved.receivedTimeMillis else generatePduCompatTimestamp(retrieved.receivedTimeMillis), DATE_RECEIVED to if (retrieved.isPushMessage) retrieved.receivedTimeMillis else generatePduCompatTimestamp(retrieved.receivedTimeMillis),
SMS_SUBSCRIPTION_ID to retrieved.subscriptionId, SMS_SUBSCRIPTION_ID to retrieved.subscriptionId,
@@ -2616,7 +2614,7 @@ open class MessageTable(context: Context?, databaseHelper: SignalDatabase) : Dat
VIEW_ONCE to if (retrieved.isViewOnce) 1 else 0, VIEW_ONCE to if (retrieved.isViewOnce) 1 else 0,
STORY_TYPE to retrieved.storyType.code, STORY_TYPE to retrieved.storyType.code,
PARENT_STORY_ID to if (retrieved.parentStoryId != null) retrieved.parentStoryId.serialize() else 0, PARENT_STORY_ID to if (retrieved.parentStoryId != null) retrieved.parentStoryId.serialize() else 0,
READ to if (silentUpdate || retrieved.isExpirationUpdate) 1 else 0, READ to if (MessageTypes.isGroupUpdate(type) || retrieved.isExpirationUpdate) 1 else 0,
UNIDENTIFIED to retrieved.isUnidentified, UNIDENTIFIED to retrieved.isUnidentified,
SERVER_GUID to retrieved.serverGuid, SERVER_GUID to retrieved.serverGuid,
LATEST_REVISION_ID to null, LATEST_REVISION_ID to null,
@@ -2687,7 +2685,7 @@ open class MessageTable(context: Context?, databaseHelper: SignalDatabase) : Dat
val isNotStoryGroupReply = retrieved.parentStoryId == null || !retrieved.parentStoryId.isGroupReply() val isNotStoryGroupReply = retrieved.parentStoryId == null || !retrieved.parentStoryId.isGroupReply()
if (!MessageTypes.isPaymentsActivated(mailbox) && !MessageTypes.isPaymentsRequestToActivate(mailbox) && !MessageTypes.isExpirationTimerUpdate(mailbox) && !retrieved.storyType.isStory && isNotStoryGroupReply) { if (!MessageTypes.isPaymentsActivated(type) && !MessageTypes.isPaymentsRequestToActivate(type) && !MessageTypes.isExpirationTimerUpdate(type) && !retrieved.storyType.isStory && isNotStoryGroupReply) {
val incrementUnreadMentions = retrieved.mentions.isNotEmpty() && retrieved.mentions.any { it.recipientId == Recipient.self().id } val incrementUnreadMentions = retrieved.mentions.isNotEmpty() && retrieved.mentions.any { it.recipientId == Recipient.self().id }
threads.incrementUnread(threadId, 1, if (incrementUnreadMentions) 1 else 0) threads.incrementUnread(threadId, 1, if (incrementUnreadMentions) 1 else 0)
ThreadUpdateJob.enqueue(threadId) ThreadUpdateJob.enqueue(threadId)
@@ -2704,91 +2702,6 @@ open class MessageTable(context: Context?, databaseHelper: SignalDatabase) : Dat
return Optional.of(InsertResult(messageId, threadId, insertedAttachments = insertedAttachments)) return Optional.of(InsertResult(messageId, threadId, insertedAttachments = insertedAttachments))
} }
@Throws(MmsException::class)
fun insertMessageInbox(
retrieved: IncomingMediaMessage,
contentLocation: String,
threadId: Long
): Optional<InsertResult> {
var type = MessageTypes.BASE_INBOX_TYPE
if (retrieved.isPushMessage) {
type = type or MessageTypes.PUSH_MESSAGE_BIT
}
if (retrieved.isExpirationUpdate) {
type = type or MessageTypes.EXPIRATION_TIMER_UPDATE_BIT
}
if (retrieved.isPaymentsNotification) {
type = type or MessageTypes.SPECIAL_TYPE_PAYMENTS_NOTIFICATION
}
if (retrieved.isActivatePaymentsRequest) {
type = type or MessageTypes.SPECIAL_TYPE_PAYMENTS_ACTIVATE_REQUEST
}
if (retrieved.isPaymentsActivated) {
type = type or MessageTypes.SPECIAL_TYPE_PAYMENTS_ACTIVATED
}
return insertMessageInbox(retrieved, contentLocation, threadId, type, editedMessage = null, notifyObservers = true)
}
@JvmOverloads
@Throws(MmsException::class)
fun insertSecureDecryptedMessageInbox(retrieved: IncomingMediaMessage, threadId: Long, edittedMediaMessage: MediaMmsMessageRecord? = null, notifyObservers: Boolean = true): Optional<InsertResult> {
var type = MessageTypes.BASE_INBOX_TYPE or MessageTypes.SECURE_MESSAGE_BIT
var hasSpecialType = false
if (retrieved.isPushMessage) {
type = type or MessageTypes.PUSH_MESSAGE_BIT
}
if (retrieved.isExpirationUpdate) {
type = type or MessageTypes.EXPIRATION_TIMER_UPDATE_BIT
}
if (retrieved.isStoryReaction) {
type = type or MessageTypes.SPECIAL_TYPE_STORY_REACTION
hasSpecialType = true
}
if (retrieved.giftBadge != null) {
if (hasSpecialType) {
throw MmsException("Cannot insert message with multiple special types.")
}
type = type or MessageTypes.SPECIAL_TYPE_GIFT_BADGE
hasSpecialType = true
}
if (retrieved.isPaymentsNotification) {
if (hasSpecialType) {
throw MmsException("Cannot insert message with multiple special types.")
}
type = type or MessageTypes.SPECIAL_TYPE_PAYMENTS_NOTIFICATION
hasSpecialType = true
}
if (retrieved.isActivatePaymentsRequest) {
if (hasSpecialType) {
throw MmsException("Cannot insert message with multiple special types.")
}
type = type or MessageTypes.SPECIAL_TYPE_PAYMENTS_ACTIVATE_REQUEST
hasSpecialType = true
}
if (retrieved.isPaymentsActivated) {
if (hasSpecialType) {
throw MmsException("Cannot insert message with multiple special types.")
}
type = type or MessageTypes.SPECIAL_TYPE_PAYMENTS_ACTIVATED
hasSpecialType = true
}
return insertMessageInbox(retrieved, "", threadId, type, edittedMediaMessage, notifyObservers)
}
fun insertChatSessionRefreshedMessage(recipientId: RecipientId, senderDeviceId: Long, sentTimestamp: Long): InsertResult { fun insertChatSessionRefreshedMessage(recipientId: RecipientId, senderDeviceId: Long, sentTimestamp: Long): InsertResult {
val threadId = threads.getOrCreateThreadIdFor(Recipient.resolved(recipientId)) val threadId = threads.getOrCreateThreadIdFor(Recipient.resolved(recipientId))
var type = MessageTypes.SECURE_MESSAGE_BIT or MessageTypes.PUSH_MESSAGE_BIT var type = MessageTypes.SECURE_MESSAGE_BIT or MessageTypes.PUSH_MESSAGE_BIT
@@ -4909,18 +4822,66 @@ open class MessageTable(context: Context?, databaseHelper: SignalDatabase) : Dat
) )
} }
private fun ByteArray?.toIsoString(): String? {
return if (this != null) {
Util.toIsoString(this)
} else {
null
}
}
private fun MessageRecord.getOriginalOrOwnMessageId(): MessageId { private fun MessageRecord.getOriginalOrOwnMessageId(): MessageId {
return this.originalMessageId ?: MessageId(this.id) return this.originalMessageId ?: MessageId(this.id)
} }
/**
* Determines the database type bitmask for theh inbound message.
*/
@Throws(MmsException::class)
private fun IncomingMediaMessage.toMessageType(): Long {
var type = MessageTypes.BASE_INBOX_TYPE or MessageTypes.SECURE_MESSAGE_BIT
var hasSpecialType = false
if (this.isPushMessage) {
type = type or MessageTypes.PUSH_MESSAGE_BIT
}
if (this.isExpirationUpdate) {
type = type or MessageTypes.EXPIRATION_TIMER_UPDATE_BIT
}
if (this.isStoryReaction) {
type = type or MessageTypes.SPECIAL_TYPE_STORY_REACTION
hasSpecialType = true
}
if (this.giftBadge != null) {
if (hasSpecialType) {
throw MmsException("Cannot insert message with multiple special types.")
}
type = type or MessageTypes.SPECIAL_TYPE_GIFT_BADGE
hasSpecialType = true
}
if (this.isPaymentsNotification) {
if (hasSpecialType) {
throw MmsException("Cannot insert message with multiple special types.")
}
type = type or MessageTypes.SPECIAL_TYPE_PAYMENTS_NOTIFICATION
hasSpecialType = true
}
if (this.isActivatePaymentsRequest) {
if (hasSpecialType) {
throw MmsException("Cannot insert message with multiple special types.")
}
type = type or MessageTypes.SPECIAL_TYPE_PAYMENTS_ACTIVATE_REQUEST
hasSpecialType = true
}
if (this.isPaymentsActivated) {
if (hasSpecialType) {
throw MmsException("Cannot insert message with multiple special types.")
}
type = type or MessageTypes.SPECIAL_TYPE_PAYMENTS_ACTIVATED
hasSpecialType = true
}
return type
}
protected enum class ReceiptType(val columnName: String, val groupStatus: Int) { protected enum class ReceiptType(val columnName: String, val groupStatus: Int) {
READ(READ_RECEIPT_COUNT, GroupReceiptTable.STATUS_READ), READ(READ_RECEIPT_COUNT, GroupReceiptTable.STATUS_READ),
DELIVERY(DELIVERY_RECEIPT_COUNT, GroupReceiptTable.STATUS_DELIVERED), DELIVERY(DELIVERY_RECEIPT_COUNT, GroupReceiptTable.STATUS_DELIVERED),

View File

@@ -330,7 +330,7 @@ object DataMessageProcessor {
isPushMessage = true isPushMessage = true
) )
val insertResult: InsertResult? = SignalDatabase.messages.insertSecureDecryptedMessageInbox(mediaMessage, -1).orNull() val insertResult: InsertResult? = SignalDatabase.messages.insertMessageInbox(mediaMessage, -1).orNull()
SignalDatabase.recipients.setExpireMessages(threadRecipientId, expiresIn.inWholeSeconds.toInt()) SignalDatabase.recipients.setExpireMessages(threadRecipientId, expiresIn.inWholeSeconds.toInt())
if (insertResult != null) { if (insertResult != null) {
@@ -433,7 +433,7 @@ object DataMessageProcessor {
serverGuid = envelope.serverGuid serverGuid = envelope.serverGuid
) )
val insertResult: InsertResult? = SignalDatabase.messages.insertSecureDecryptedMessageInbox(mediaMessage, -1).orNull() val insertResult: InsertResult? = SignalDatabase.messages.insertMessageInbox(mediaMessage, -1).orNull()
if (insertResult != null) { if (insertResult != null) {
SignalDatabase.messages.setTransactionSuccessful() SignalDatabase.messages.setTransactionSuccessful()
@@ -595,7 +595,7 @@ object DataMessageProcessor {
isPaymentsActivated = isPaymentsActivated isPaymentsActivated = isPaymentsActivated
) )
val insertResult: InsertResult? = SignalDatabase.messages.insertSecureDecryptedMessageInbox(mediaMessage, -1).orNull() val insertResult: InsertResult? = SignalDatabase.messages.insertMessageInbox(mediaMessage, -1).orNull()
if (insertResult != null) { if (insertResult != null) {
return MessageId(insertResult.messageId) return MessageId(insertResult.messageId)
@@ -651,7 +651,7 @@ object DataMessageProcessor {
isPaymentsNotification = true isPaymentsNotification = true
) )
val insertResult: InsertResult? = SignalDatabase.messages.insertSecureDecryptedMessageInbox(mediaMessage, -1).orNull() val insertResult: InsertResult? = SignalDatabase.messages.insertMessageInbox(mediaMessage, -1).orNull()
if (insertResult != null) { if (insertResult != null) {
val messageId = MessageId(insertResult.messageId) val messageId = MessageId(insertResult.messageId)
ApplicationDependencies.getMessageNotifier().updateNotification(context, ConversationId.forConversation(insertResult.threadId)) ApplicationDependencies.getMessageNotifier().updateNotification(context, ConversationId.forConversation(insertResult.threadId))
@@ -766,7 +766,7 @@ object DataMessageProcessor {
messageRanges = bodyRanges messageRanges = bodyRanges
) )
val insertResult: InsertResult? = SignalDatabase.messages.insertSecureDecryptedMessageInbox(mediaMessage, -1).orNull() val insertResult: InsertResult? = SignalDatabase.messages.insertMessageInbox(mediaMessage, -1).orNull()
if (insertResult != null) { if (insertResult != null) {
SignalDatabase.messages.setTransactionSuccessful() SignalDatabase.messages.setTransactionSuccessful()
@@ -830,7 +830,7 @@ object DataMessageProcessor {
giftBadge = dbGiftBadge giftBadge = dbGiftBadge
) )
SignalDatabase.messages.insertSecureDecryptedMessageInbox(mediaMessage, -1).orNull() SignalDatabase.messages.insertMessageInbox(mediaMessage, -1).orNull()
} catch (e: MmsException) { } catch (e: MmsException) {
throw StorageFailedException(e, metadata.sourceServiceId.toString(), metadata.sourceDeviceId) throw StorageFailedException(e, metadata.sourceServiceId.toString(), metadata.sourceDeviceId)
} }
@@ -894,7 +894,7 @@ object DataMessageProcessor {
isPushMessage = true isPushMessage = true
) )
insertResult = SignalDatabase.messages.insertSecureDecryptedMessageInbox(mediaMessage, -1).orNull() insertResult = SignalDatabase.messages.insertMessageInbox(mediaMessage, -1).orNull()
if (insertResult != null) { if (insertResult != null) {
SignalDatabase.messages.setTransactionSuccessful() SignalDatabase.messages.setTransactionSuccessful()
} }

View File

@@ -77,7 +77,7 @@ object StoryMessageProcessor {
messageRanges = storyMessage.bodyRanges.filter { it.mentionAci == null }.toBodyRangeList() messageRanges = storyMessage.bodyRanges.filter { it.mentionAci == null }.toBodyRangeList()
) )
insertResult = SignalDatabase.messages.insertSecureDecryptedMessageInbox(mediaMessage, -1).orNull() insertResult = SignalDatabase.messages.insertMessageInbox(mediaMessage, -1).orNull()
if (insertResult != null) { if (insertResult != null) {
SignalDatabase.messages.setTransactionSuccessful() SignalDatabase.messages.setTransactionSuccessful()
} }

View File

@@ -72,6 +72,6 @@ object ReleaseChannel {
storyType = storyType storyType = storyType
) )
return SignalDatabase.messages.insertSecureDecryptedMessageInbox(message, threadId).orElse(null) return SignalDatabase.messages.insertMessageInbox(message, threadId).orElse(null)
} }
} }