mirror of
https://github.com/oxen-io/session-android.git
synced 2024-11-30 13:35:18 +00:00
refactor: inserting attachments with the messages so that they are linked properly to a mmsID
This commit is contained in:
parent
323fb75149
commit
817c40b30c
@ -15,7 +15,7 @@ import org.session.libsession.messaging.messages.visible.Attachment
|
|||||||
import org.session.libsession.messaging.messages.visible.VisibleMessage
|
import org.session.libsession.messaging.messages.visible.VisibleMessage
|
||||||
import org.session.libsession.messaging.opengroups.OpenGroup
|
import org.session.libsession.messaging.opengroups.OpenGroup
|
||||||
import org.session.libsession.messaging.sending_receiving.attachments.AttachmentId
|
import org.session.libsession.messaging.sending_receiving.attachments.AttachmentId
|
||||||
import org.session.libsession.messaging.sending_receiving.attachments.PointerAttachment
|
import org.session.libsession.messaging.sending_receiving.attachments.DatabaseAttachment
|
||||||
import org.session.libsession.messaging.sending_receiving.linkpreview.LinkPreview
|
import org.session.libsession.messaging.sending_receiving.linkpreview.LinkPreview
|
||||||
import org.session.libsession.messaging.sending_receiving.quotes.QuoteModel
|
import org.session.libsession.messaging.sending_receiving.quotes.QuoteModel
|
||||||
import org.session.libsession.messaging.threads.Address
|
import org.session.libsession.messaging.threads.Address
|
||||||
@ -27,13 +27,11 @@ import org.session.libsession.utilities.preferences.ProfileKeyUtil
|
|||||||
import org.session.libsignal.libsignal.ecc.ECKeyPair
|
import org.session.libsignal.libsignal.ecc.ECKeyPair
|
||||||
import org.session.libsignal.libsignal.util.KeyHelper
|
import org.session.libsignal.libsignal.util.KeyHelper
|
||||||
import org.session.libsignal.libsignal.util.guava.Optional
|
import org.session.libsignal.libsignal.util.guava.Optional
|
||||||
import org.session.libsignal.service.api.messages.SignalServiceAttachment
|
|
||||||
import org.session.libsignal.service.api.messages.SignalServiceAttachmentPointer
|
import org.session.libsignal.service.api.messages.SignalServiceAttachmentPointer
|
||||||
import org.session.libsignal.service.api.messages.SignalServiceGroup
|
import org.session.libsignal.service.api.messages.SignalServiceGroup
|
||||||
import org.session.libsignal.service.internal.push.SignalServiceProtos
|
import org.session.libsignal.service.internal.push.SignalServiceProtos
|
||||||
import org.session.libsignal.service.loki.api.opengroups.PublicChat
|
import org.session.libsignal.service.loki.api.opengroups.PublicChat
|
||||||
import org.session.libsignal.utilities.logging.Log
|
import org.session.libsignal.utilities.logging.Log
|
||||||
import org.thoughtcrime.securesms.attachments.toSignalPointer
|
|
||||||
import org.thoughtcrime.securesms.crypto.IdentityKeyUtil
|
import org.thoughtcrime.securesms.crypto.IdentityKeyUtil
|
||||||
import org.thoughtcrime.securesms.database.helpers.SQLCipherOpenHelper
|
import org.thoughtcrime.securesms.database.helpers.SQLCipherOpenHelper
|
||||||
import org.thoughtcrime.securesms.loki.database.LokiThreadDatabase
|
import org.thoughtcrime.securesms.loki.database.LokiThreadDatabase
|
||||||
@ -94,17 +92,24 @@ class Storage(context: Context, helper: SQLCipherOpenHelper) : Database(context,
|
|||||||
return database.insertAttachments(messageId, databaseAttachments)
|
return database.insertAttachments(messageId, databaseAttachments)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun persist(message: VisibleMessage, quotes: QuoteModel?, linkPreview: List<LinkPreview?>, groupPublicKey: String?, openGroupID: String?): Long? {
|
override fun getAttachmentsForMessage(messageId: Long): List<DatabaseAttachment> {
|
||||||
|
val database = DatabaseFactory.getAttachmentDatabase(context)
|
||||||
|
return database.getAttachmentsForMessage(messageId)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun persist(message: VisibleMessage, quotes: QuoteModel?, linkPreview: List<LinkPreview?>, groupPublicKey: String?, openGroupID: String?, attachments: List<Attachment>): Long? {
|
||||||
var messageID: Long? = null
|
var messageID: Long? = null
|
||||||
val senderAddress = Address.fromSerialized(message.sender!!)
|
val senderAddress = Address.fromSerialized(message.sender!!)
|
||||||
val senderRecipient = Recipient.from(context, senderAddress, false)
|
val senderRecipient = Recipient.from(context, senderAddress, false)
|
||||||
var group: Optional<SignalServiceGroup> = Optional.absent()
|
val group: Optional<SignalServiceGroup> = when {
|
||||||
if (openGroupID != null) {
|
openGroupID != null -> Optional.of(SignalServiceGroup(openGroupID.toByteArray(), SignalServiceGroup.GroupType.PUBLIC_CHAT))
|
||||||
group = Optional.of(SignalServiceGroup(openGroupID.toByteArray(), SignalServiceGroup.GroupType.PUBLIC_CHAT))
|
groupPublicKey != null -> Optional.of(SignalServiceGroup(groupPublicKey.toByteArray(), SignalServiceGroup.GroupType.SIGNAL))
|
||||||
} else if (groupPublicKey != null) {
|
else -> Optional.absent()
|
||||||
group = Optional.of(SignalServiceGroup(groupPublicKey.toByteArray(), SignalServiceGroup.GroupType.SIGNAL))
|
|
||||||
}
|
}
|
||||||
if (message.isMediaMessage()) {
|
val pointerAttachments = attachments.mapNotNull {
|
||||||
|
it.toSignalAttachment()
|
||||||
|
}
|
||||||
|
if (message.isMediaMessage() || attachments.isNotEmpty()) {
|
||||||
val quote: Optional<QuoteModel> = if (quotes != null) Optional.of(quotes) else Optional.absent()
|
val quote: Optional<QuoteModel> = if (quotes != null) Optional.of(quotes) else Optional.absent()
|
||||||
val linkPreviews: Optional<List<LinkPreview>> = if (linkPreview.isEmpty()) Optional.absent() else Optional.of(linkPreview.mapNotNull { it!! })
|
val linkPreviews: Optional<List<LinkPreview>> = if (linkPreview.isEmpty()) Optional.absent() else Optional.of(linkPreview.mapNotNull { it!! })
|
||||||
val mmsDatabase = DatabaseFactory.getMmsDatabase(context)
|
val mmsDatabase = DatabaseFactory.getMmsDatabase(context)
|
||||||
@ -119,20 +124,16 @@ class Storage(context: Context, helper: SQLCipherOpenHelper) : Database(context,
|
|||||||
return null
|
return null
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
val attachments = message.attachmentIDs.mapNotNull {
|
|
||||||
DatabaseFactory.getAttachmentProvider(context).getSignalAttachmentPointer(it)
|
val mediaMessage = OutgoingMediaMessage.from(message, Recipient.from(context, targetAddress, false), pointerAttachments, quote.orNull(), linkPreviews.orNull().firstOrNull())
|
||||||
}.mapNotNull {
|
|
||||||
PointerAttachment.forPointer(Optional.of(it)).orNull()
|
|
||||||
}
|
|
||||||
val mediaMessage = OutgoingMediaMessage.from(message, Recipient.from(context, targetAddress, false), attachments, quote.orNull(), linkPreviews.orNull().firstOrNull())
|
|
||||||
mmsDatabase.beginTransaction()
|
mmsDatabase.beginTransaction()
|
||||||
mmsDatabase.insertSecureDecryptedMessageOutbox(mediaMessage, message.threadID ?: -1, message.sentTimestamp!!)
|
mmsDatabase.insertSecureDecryptedMessageOutbox(mediaMessage, message.threadID ?: -1, message.sentTimestamp!!)
|
||||||
} else {
|
} else {
|
||||||
// It seems like we have replaced SignalServiceAttachment with SessionServiceAttachment
|
// It seems like we have replaced SignalServiceAttachment with SessionServiceAttachment
|
||||||
val attachments: Optional<List<SignalServiceAttachment>> = Optional.of(message.attachmentIDs.mapNotNull {
|
val signalServiceAttachments = attachments.mapNotNull {
|
||||||
DatabaseFactory.getAttachmentProvider(context).getAttachmentPointer(it)?.toSignalPointer()
|
it.toSignalPointer()
|
||||||
})
|
}
|
||||||
val mediaMessage = IncomingMediaMessage.from(message, senderAddress, senderRecipient.expireMessages * 1000L, group, attachments, quote, linkPreviews)
|
val mediaMessage = IncomingMediaMessage.from(message, senderAddress, senderRecipient.expireMessages * 1000L, group, signalServiceAttachments, quote, linkPreviews)
|
||||||
mmsDatabase.beginTransaction()
|
mmsDatabase.beginTransaction()
|
||||||
if (group.isPresent) {
|
if (group.isPresent) {
|
||||||
mmsDatabase.insertSecureDecryptedMessageInbox(mediaMessage, message.threadID ?: -1, message.sentTimestamp!!)
|
mmsDatabase.insertSecureDecryptedMessageInbox(mediaMessage, message.threadID ?: -1, message.sentTimestamp!!)
|
||||||
|
@ -3,10 +3,10 @@ package org.thoughtcrime.securesms.mms;
|
|||||||
import org.session.libsession.messaging.messages.visible.VisibleMessage;
|
import org.session.libsession.messaging.messages.visible.VisibleMessage;
|
||||||
import org.session.libsession.messaging.sending_receiving.attachments.Attachment;
|
import org.session.libsession.messaging.sending_receiving.attachments.Attachment;
|
||||||
import org.session.libsession.messaging.sending_receiving.attachments.PointerAttachment;
|
import org.session.libsession.messaging.sending_receiving.attachments.PointerAttachment;
|
||||||
import org.session.libsession.messaging.sending_receiving.sharecontacts.Contact;
|
|
||||||
import org.session.libsession.messaging.threads.Address;
|
|
||||||
import org.session.libsession.messaging.sending_receiving.linkpreview.LinkPreview;
|
import org.session.libsession.messaging.sending_receiving.linkpreview.LinkPreview;
|
||||||
import org.session.libsession.messaging.sending_receiving.quotes.QuoteModel;
|
import org.session.libsession.messaging.sending_receiving.quotes.QuoteModel;
|
||||||
|
import org.session.libsession.messaging.sending_receiving.sharecontacts.Contact;
|
||||||
|
import org.session.libsession.messaging.threads.Address;
|
||||||
import org.session.libsession.utilities.GroupUtil;
|
import org.session.libsession.utilities.GroupUtil;
|
||||||
import org.session.libsignal.libsignal.util.guava.Optional;
|
import org.session.libsignal.libsignal.util.guava.Optional;
|
||||||
import org.session.libsignal.service.api.messages.SignalServiceAttachment;
|
import org.session.libsignal.service.api.messages.SignalServiceAttachment;
|
||||||
@ -68,12 +68,12 @@ public class IncomingMediaMessage {
|
|||||||
Address from,
|
Address from,
|
||||||
long expiresIn,
|
long expiresIn,
|
||||||
Optional<SignalServiceGroup> group,
|
Optional<SignalServiceGroup> group,
|
||||||
Optional<List<SignalServiceAttachment>> attachments,
|
List<SignalServiceAttachment> attachments,
|
||||||
Optional<QuoteModel> quote,
|
Optional<QuoteModel> quote,
|
||||||
Optional<List<LinkPreview>> linkPreviews)
|
Optional<List<LinkPreview>> linkPreviews)
|
||||||
{
|
{
|
||||||
return new IncomingMediaMessage(from, message.getReceivedTimestamp(), -1, expiresIn, false,
|
return new IncomingMediaMessage(from, message.getReceivedTimestamp(), -1, expiresIn, false,
|
||||||
false, Optional.fromNullable(message.getText()), group, attachments, quote, Optional.absent(), linkPreviews);
|
false, Optional.fromNullable(message.getText()), group, Optional.fromNullable(attachments), quote, Optional.absent(), linkPreviews);
|
||||||
}
|
}
|
||||||
|
|
||||||
public int getSubscriptionId() {
|
public int getSubscriptionId() {
|
||||||
|
@ -6,18 +6,17 @@ import android.net.Uri
|
|||||||
import org.session.libsession.messaging.jobs.AttachmentUploadJob
|
import org.session.libsession.messaging.jobs.AttachmentUploadJob
|
||||||
import org.session.libsession.messaging.jobs.Job
|
import org.session.libsession.messaging.jobs.Job
|
||||||
import org.session.libsession.messaging.jobs.MessageSendJob
|
import org.session.libsession.messaging.jobs.MessageSendJob
|
||||||
import org.session.libsession.messaging.messages.Message
|
|
||||||
import org.session.libsession.messaging.messages.visible.Attachment
|
import org.session.libsession.messaging.messages.visible.Attachment
|
||||||
import org.session.libsession.messaging.messages.visible.VisibleMessage
|
import org.session.libsession.messaging.messages.visible.VisibleMessage
|
||||||
import org.session.libsession.messaging.opengroups.OpenGroup
|
import org.session.libsession.messaging.opengroups.OpenGroup
|
||||||
import org.session.libsession.messaging.sending_receiving.attachments.AttachmentId
|
import org.session.libsession.messaging.sending_receiving.attachments.AttachmentId
|
||||||
|
import org.session.libsession.messaging.sending_receiving.attachments.DatabaseAttachment
|
||||||
import org.session.libsession.messaging.sending_receiving.linkpreview.LinkPreview
|
import org.session.libsession.messaging.sending_receiving.linkpreview.LinkPreview
|
||||||
import org.session.libsession.messaging.sending_receiving.quotes.QuoteModel
|
import org.session.libsession.messaging.sending_receiving.quotes.QuoteModel
|
||||||
import org.session.libsession.messaging.threads.Address
|
import org.session.libsession.messaging.threads.Address
|
||||||
import org.session.libsession.messaging.threads.GroupRecord
|
import org.session.libsession.messaging.threads.GroupRecord
|
||||||
import org.session.libsession.messaging.threads.recipients.Recipient.RecipientSettings
|
import org.session.libsession.messaging.threads.recipients.Recipient.RecipientSettings
|
||||||
import org.session.libsignal.libsignal.ecc.ECKeyPair
|
import org.session.libsignal.libsignal.ecc.ECKeyPair
|
||||||
import org.session.libsignal.libsignal.ecc.ECPrivateKey
|
|
||||||
import org.session.libsignal.service.api.messages.SignalServiceAttachmentPointer
|
import org.session.libsignal.service.api.messages.SignalServiceAttachmentPointer
|
||||||
import org.session.libsignal.service.api.messages.SignalServiceGroup
|
import org.session.libsignal.service.api.messages.SignalServiceGroup
|
||||||
import org.session.libsignal.service.internal.push.SignalServiceProtos
|
import org.session.libsignal.service.internal.push.SignalServiceProtos
|
||||||
@ -92,6 +91,7 @@ interface StorageProtocol {
|
|||||||
// fun removeReceivedMessageTimestamps(timestamps: Set<Long>)
|
// fun removeReceivedMessageTimestamps(timestamps: Set<Long>)
|
||||||
// Returns the IDs of the saved attachments.
|
// Returns the IDs of the saved attachments.
|
||||||
fun persistAttachments(messageId: Long, attachments: List<Attachment>): List<Long>
|
fun persistAttachments(messageId: Long, attachments: List<Attachment>): List<Long>
|
||||||
|
fun getAttachmentsForMessage(messageId: Long): List<DatabaseAttachment>
|
||||||
|
|
||||||
fun getMessageIdInDatabase(timestamp: Long, author: String): Long?
|
fun getMessageIdInDatabase(timestamp: Long, author: String): Long?
|
||||||
fun setOpenGroupServerMessageID(messageID: Long, serverID: Long)
|
fun setOpenGroupServerMessageID(messageID: Long, serverID: Long)
|
||||||
@ -150,5 +150,5 @@ interface StorageProtocol {
|
|||||||
|
|
||||||
// Message Handling
|
// Message Handling
|
||||||
/// Returns the ID of the `TSIncomingMessage` that was constructed.
|
/// Returns the ID of the `TSIncomingMessage` that was constructed.
|
||||||
fun persist(message: VisibleMessage, quotes: QuoteModel?, linkPreview: List<LinkPreview?>, groupPublicKey: String?, openGroupID: String?): Long?
|
fun persist(message: VisibleMessage, quotes: QuoteModel?, linkPreview: List<LinkPreview?>, groupPublicKey: String?, openGroupID: String?, attachments: List<Attachment>): Long?
|
||||||
}
|
}
|
@ -4,6 +4,7 @@ import android.util.Size
|
|||||||
import android.webkit.MimeTypeMap
|
import android.webkit.MimeTypeMap
|
||||||
import com.google.protobuf.ByteString
|
import com.google.protobuf.ByteString
|
||||||
import org.session.libsession.messaging.sending_receiving.attachments.DatabaseAttachment
|
import org.session.libsession.messaging.sending_receiving.attachments.DatabaseAttachment
|
||||||
|
import org.session.libsignal.libsignal.util.guava.Optional
|
||||||
import org.session.libsignal.service.api.messages.SignalServiceAttachmentPointer
|
import org.session.libsignal.service.api.messages.SignalServiceAttachmentPointer
|
||||||
import org.session.libsignal.service.internal.push.SignalServiceProtos
|
import org.session.libsignal.service.internal.push.SignalServiceProtos
|
||||||
import org.session.libsignal.utilities.Base64
|
import org.session.libsignal.utilities.Base64
|
||||||
@ -23,7 +24,7 @@ class Attachment {
|
|||||||
var url: String? = null
|
var url: String? = null
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
fun fromProto(proto: SignalServiceProtos.AttachmentPointer): Attachment? {
|
fun fromProto(proto: SignalServiceProtos.AttachmentPointer): Attachment {
|
||||||
val result = Attachment()
|
val result = Attachment()
|
||||||
result.fileName = proto.fileName
|
result.fileName = proto.fileName
|
||||||
fun inferContentType(): String {
|
fun inferContentType(): String {
|
||||||
@ -104,4 +105,12 @@ class Attachment {
|
|||||||
sizeInBytes?.toLong() ?: 0, if (fileName.isNullOrEmpty()) null else fileName, null, Base64.encodeBytes(key), null, digest, null, kind == Kind.VOICE_MESSAGE,
|
sizeInBytes?.toLong() ?: 0, if (fileName.isNullOrEmpty()) null else fileName, null, Base64.encodeBytes(key), null, digest, null, kind == Kind.VOICE_MESSAGE,
|
||||||
size?.width ?: 0, size?.height ?: 0, false, caption, url)
|
size?.width ?: 0, size?.height ?: 0, false, caption, url)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun toSignalPointer(): SignalServiceAttachmentPointer? {
|
||||||
|
if (!isValid()) return null
|
||||||
|
return SignalServiceAttachmentPointer(0, contentType, key, Optional.fromNullable(sizeInBytes), null,
|
||||||
|
size?.width ?: 0, size?.height ?: 0, Optional.fromNullable(digest), Optional.fromNullable(fileName),
|
||||||
|
kind == Kind.VOICE_MESSAGE, Optional.fromNullable(caption), url)
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
@ -123,17 +123,6 @@ private fun MessageReceiver.handleConfigurationMessage(message: ConfigurationMes
|
|||||||
fun MessageReceiver.handleVisibleMessage(message: VisibleMessage, proto: SignalServiceProtos.Content, openGroupID: String?) {
|
fun MessageReceiver.handleVisibleMessage(message: VisibleMessage, proto: SignalServiceProtos.Content, openGroupID: String?) {
|
||||||
val storage = MessagingConfiguration.shared.storage
|
val storage = MessagingConfiguration.shared.storage
|
||||||
val context = MessagingConfiguration.shared.context
|
val context = MessagingConfiguration.shared.context
|
||||||
// Parse & persist attachments
|
|
||||||
val attachments = proto.dataMessage.attachmentsList.mapNotNull { proto ->
|
|
||||||
val attachment = Attachment.fromProto(proto)
|
|
||||||
if (attachment == null || !attachment.isValid()) {
|
|
||||||
return@mapNotNull null
|
|
||||||
} else {
|
|
||||||
return@mapNotNull attachment
|
|
||||||
}
|
|
||||||
}
|
|
||||||
val attachmentIDs = storage.persistAttachments(message.id ?: 0, attachments)
|
|
||||||
message.attachmentIDs.addAll(attachmentIDs.toMutableList())
|
|
||||||
// Update profile if needed
|
// Update profile if needed
|
||||||
val newProfile = message.profile
|
val newProfile = message.profile
|
||||||
if (newProfile != null) {
|
if (newProfile != null) {
|
||||||
@ -187,15 +176,26 @@ fun MessageReceiver.handleVisibleMessage(message: VisibleMessage, proto: SignalS
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
val attachments = proto.dataMessage.attachmentsList.mapNotNull { proto ->
|
||||||
|
val attachment = Attachment.fromProto(proto)
|
||||||
|
if (!attachment.isValid()) {
|
||||||
|
return@mapNotNull null
|
||||||
|
} else {
|
||||||
|
return@mapNotNull attachment
|
||||||
|
}
|
||||||
|
}
|
||||||
// Parse stickers if needed
|
// Parse stickers if needed
|
||||||
// Persist the message
|
// Persist the message
|
||||||
val messageID = storage.persist(message, quoteModel, linkPreviews, message.groupPublicKey, openGroupID) ?: throw MessageReceiver.Error.NoThread
|
val messageID = storage.persist(message, quoteModel, linkPreviews, message.groupPublicKey, openGroupID, attachments) ?: throw MessageReceiver.Error.NoThread
|
||||||
message.threadID = threadID
|
message.threadID = threadID
|
||||||
|
// Parse & persist attachments
|
||||||
// Start attachment downloads if needed
|
// Start attachment downloads if needed
|
||||||
attachmentIDs.forEach { attachmentID ->
|
storage.getAttachmentsForMessage(messageID).forEach { attachment ->
|
||||||
val downloadJob = AttachmentDownloadJob(attachmentID, messageID)
|
attachment.attachmentId?.let { id ->
|
||||||
|
val downloadJob = AttachmentDownloadJob(id.rowId, messageID)
|
||||||
JobQueue.shared.add(downloadJob)
|
JobQueue.shared.add(downloadJob)
|
||||||
}
|
}
|
||||||
|
}
|
||||||
// Cancel any typing indicators if needed
|
// Cancel any typing indicators if needed
|
||||||
cancelTypingIndicatorsIfNeeded(message.sender!!)
|
cancelTypingIndicatorsIfNeeded(message.sender!!)
|
||||||
//Notify the user if needed
|
//Notify the user if needed
|
||||||
|
Loading…
Reference in New Issue
Block a user