complete message sender

This commit is contained in:
Ryan ZHAO 2021-01-20 16:29:52 +11:00
parent a9df948375
commit f3c3483cde
8 changed files with 79 additions and 21 deletions

View File

@ -78,6 +78,15 @@ public class MmsSmsDatabase extends Database {
super(context, databaseHelper); super(context, databaseHelper);
} }
public @Nullable MessageRecord getMessageFor(long messageId) {
MmsSmsDatabase db = DatabaseFactory.getMmsSmsDatabase(context);
try (Cursor cursor = queryTables(PROJECTION, MmsSmsColumns.ID + " = " + messageId, null, null)) {
MmsSmsDatabase.Reader reader = db.readerFor(cursor);
return reader.getNext();
}
}
public @Nullable MessageRecord getMessageFor(long timestamp, Address author) { public @Nullable MessageRecord getMessageFor(long timestamp, Address author) {
MmsSmsDatabase db = DatabaseFactory.getMmsSmsDatabase(context); MmsSmsDatabase db = DatabaseFactory.getMmsSmsDatabase(context);

View File

@ -253,12 +253,38 @@ class Storage(context: Context, helper: SQLCipherOpenHelper) : Database(context,
TODO("Not yet implemented") TODO("Not yet implemented")
} }
override fun insertMessageOutbox(message: Message) { override fun getMessageIdInDatabase(timestamp: Long, author: String): Long? {
TODO("Not yet implemented") val database = DatabaseFactory.getMmsSmsDatabase(context)
val address = Address.fromSerialized(author)
return database.getMessageFor(timestamp, address)?.getId()
} }
override fun insertMessageInbox(message: Message) { override fun setOpenGroupServerMessageID(messageID: Long, serverID: Long) {
TODO("Not yet implemented") DatabaseFactory.getLokiMessageDatabase(context).setServerID(messageID, serverID)
}
override fun markAsSent(messageID: Long) {
val database = DatabaseFactory.getMmsSmsDatabase(context)
val messageRecord = database.getMessageFor(messageID)!!
if (messageRecord.isMms) {
val mmsDatabase = DatabaseFactory.getMmsDatabase(context)
mmsDatabase.markAsSent(messageRecord.getId(), true)
} else {
val smsDatabase = DatabaseFactory.getSmsDatabase(context)
smsDatabase.markAsSent(messageRecord.getId(), true)
}
}
override fun markUnidentified(messageID: Long) {
val database = DatabaseFactory.getMmsSmsDatabase(context)
val messageRecord = database.getMessageFor(messageID)!!
if (messageRecord.isMms) {
val mmsDatabase = DatabaseFactory.getMmsDatabase(context)
mmsDatabase.markUnidentified(messageRecord.getId(), true)
} else {
val smsDatabase = DatabaseFactory.getSmsDatabase(context)
smsDatabase.markUnidentified(messageRecord.getId(), true)
}
} }
override fun setErrorMessage(message: Message, error: Exception) { override fun setErrorMessage(message: Message, error: Exception) {

View File

@ -103,6 +103,21 @@ public class ExpiringMessageManager implements SSKEnvironment.MessageExpirationM
setExpirationTimer(messageID, 0, senderPublicKey, content); setExpirationTimer(messageID, 0, senderPublicKey, content);
} }
@Override
public void startAnyExpiration(long messageID) {
MessageRecord messageRecord = DatabaseFactory.getMmsSmsDatabase(context).getMessageFor(messageID);
if (messageRecord != null) {
boolean mms = messageRecord.isMms();
Recipient recipient = messageRecord.getRecipient();
if (mms) {
mmsDatabase.markExpireStarted(messageID);
} else {
smsDatabase.markExpireStarted(messageID);
}
scheduleDeletion(messageID, mms, recipient.getExpireMessages());
}
}
private class LoadTask implements Runnable { private class LoadTask implements Runnable {
public void run() { public void run() {
SmsDatabase.Reader smsReader = smsDatabase.readerFor(smsDatabase.getExpirationStartedMessages()); SmsDatabase.Reader smsReader = smsDatabase.readerFor(smsDatabase.getExpirationStartedMessages());

View File

@ -87,13 +87,16 @@ interface StorageProtocol {
fun addReceivedMessageTimestamp(timestamp: Long) fun addReceivedMessageTimestamp(timestamp: Long)
// Returns the IDs of the saved attachments. // Returns the IDs of the saved attachments.
fun persist(attachments: List<Attachment>): List<Long> fun persist(attachments: List<Attachment>): List<Long>
fun insertMessageOutbox(message: Message)
fun insertMessageInbox(message: Message) fun getMessageIdInDatabase(timestamp: Long, author: String): Long?
fun setOpenGroupServerMessageID(messageID: Long, serverID: Long)
fun markAsSent(messageID: Long)
fun markUnidentified(messageID: Long)
fun setErrorMessage(message: Message, error: Exception) fun setErrorMessage(message: Message, error: Exception)
// Closed Groups // Closed Groups
fun getGroup(groupID: String): GroupRecord? fun getGroup(groupID: String): GroupRecord?
fun createGroup(groupId: String, title: String?, members: List<Address>, avatar: SignalServiceAttachmentPointer?, relay: String?, admins: List<Address>) fun createGroup(groupID: String, title: String?, members: List<Address>, avatar: SignalServiceAttachmentPointer?, relay: String?, admins: List<Address>)
fun setActive(groupID: String, value: Boolean) fun setActive(groupID: String, value: Boolean)
fun removeMember(groupID: String, member: Address) fun removeMember(groupID: String, member: Address)
fun updateMembers(groupID: String, members: List<Address>) fun updateMembers(groupID: String, members: List<Address>)

View File

@ -4,7 +4,7 @@ import org.session.libsignal.service.internal.push.SignalServiceProtos
abstract class Message { abstract class Message {
var id: String? = null var id: Long? = null
var threadID: Long? = null var threadID: Long? = null
var sentTimestamp: Long? = null var sentTimestamp: Long? = null
var receivedTimestamp: Long? = null var receivedTimestamp: Long? = null

View File

@ -70,21 +70,21 @@ fun MessageReceiver.showTypingIndicatorIfNeeded(senderPublicKey: String) {
val context = MessagingConfiguration.shared.context val context = MessagingConfiguration.shared.context
val address = Address.fromSerialized(senderPublicKey) val address = Address.fromSerialized(senderPublicKey)
val threadID = MessagingConfiguration.shared.storage.getThreadIdFor(address) ?: return val threadID = MessagingConfiguration.shared.storage.getThreadIdFor(address) ?: return
SSKEnvironment.shared.typingIndicators.didReceiveTypingStartedMessage(context, threadID.toLong(), address, 1) SSKEnvironment.shared.typingIndicators.didReceiveTypingStartedMessage(context, threadID, address, 1)
} }
fun MessageReceiver.hideTypingIndicatorIfNeeded(senderPublicKey: String) { fun MessageReceiver.hideTypingIndicatorIfNeeded(senderPublicKey: String) {
val context = MessagingConfiguration.shared.context val context = MessagingConfiguration.shared.context
val address = Address.fromSerialized(senderPublicKey) val address = Address.fromSerialized(senderPublicKey)
val threadID = MessagingConfiguration.shared.storage.getThreadIdFor(address) ?: return val threadID = MessagingConfiguration.shared.storage.getThreadIdFor(address) ?: return
SSKEnvironment.shared.typingIndicators.didReceiveTypingStoppedMessage(context, threadID.toLong(), address, 1, false) SSKEnvironment.shared.typingIndicators.didReceiveTypingStoppedMessage(context, threadID, address, 1, false)
} }
fun MessageReceiver.cancelTypingIndicatorsIfNeeded(senderPublicKey: String) { fun MessageReceiver.cancelTypingIndicatorsIfNeeded(senderPublicKey: String) {
val context = MessagingConfiguration.shared.context val context = MessagingConfiguration.shared.context
val address = Address.fromSerialized(senderPublicKey) val address = Address.fromSerialized(senderPublicKey)
val threadID = MessagingConfiguration.shared.storage.getThreadIdFor(address) ?: return val threadID = MessagingConfiguration.shared.storage.getThreadIdFor(address) ?: return
SSKEnvironment.shared.typingIndicators.didReceiveIncomingMessage(context, threadID.toLong(), address, 1) SSKEnvironment.shared.typingIndicators.didReceiveIncomingMessage(context, threadID, address, 1)
} }
private fun MessageReceiver.handleExpirationTimerUpdate(message: ExpirationTimerUpdate, proto: SignalServiceProtos.Content) { private fun MessageReceiver.handleExpirationTimerUpdate(message: ExpirationTimerUpdate, proto: SignalServiceProtos.Content) {
@ -96,14 +96,14 @@ private fun MessageReceiver.handleExpirationTimerUpdate(message: ExpirationTimer
} }
fun MessageReceiver.setExpirationTimer(message: ExpirationTimerUpdate, proto: SignalServiceProtos.Content) { fun MessageReceiver.setExpirationTimer(message: ExpirationTimerUpdate, proto: SignalServiceProtos.Content) {
val id = message.id?.toLong() val id = message.id
val duration = message.duration!! val duration = message.duration!!
val senderPublicKey = message.sender!! val senderPublicKey = message.sender!!
SSKEnvironment.shared.messageExpirationManager.setExpirationTimer(id, duration, senderPublicKey, proto) SSKEnvironment.shared.messageExpirationManager.setExpirationTimer(id, duration, senderPublicKey, proto)
} }
fun MessageReceiver.disableExpirationTimer(message: ExpirationTimerUpdate, proto: SignalServiceProtos.Content) { fun MessageReceiver.disableExpirationTimer(message: ExpirationTimerUpdate, proto: SignalServiceProtos.Content) {
val id = message.id?.toLong() val id = message.id
val senderPublicKey = message.sender!! val senderPublicKey = message.sender!!
SSKEnvironment.shared.messageExpirationManager.disableExpirationTimer(id, senderPublicKey, proto) SSKEnvironment.shared.messageExpirationManager.disableExpirationTimer(id, senderPublicKey, proto)
} }

View File

@ -3,23 +3,22 @@ package org.session.libsession.messaging.sending_receiving
import android.util.Size import android.util.Size
import nl.komponents.kovenant.Promise import nl.komponents.kovenant.Promise
import nl.komponents.kovenant.deferred import nl.komponents.kovenant.deferred
import org.session.libsession.messaging.MessagingConfiguration import org.session.libsession.messaging.MessagingConfiguration
import org.session.libsession.messaging.jobs.JobQueue import org.session.libsession.messaging.jobs.JobQueue
import org.session.libsession.messaging.jobs.NotifyPNServerJob
import org.session.libsession.messaging.messages.Destination import org.session.libsession.messaging.messages.Destination
import org.session.libsession.messaging.messages.Message import org.session.libsession.messaging.messages.Message
import org.session.libsession.messaging.messages.visible.VisibleMessage
import org.session.libsession.messaging.jobs.NotifyPNServerJob
import org.session.libsession.messaging.messages.control.ClosedGroupUpdate import org.session.libsession.messaging.messages.control.ClosedGroupUpdate
import org.session.libsession.messaging.messages.visible.Attachment import org.session.libsession.messaging.messages.visible.Attachment
import org.session.libsession.messaging.messages.visible.Profile import org.session.libsession.messaging.messages.visible.Profile
import org.session.libsession.messaging.messages.visible.VisibleMessage
import org.session.libsession.messaging.opengroups.OpenGroupAPI import org.session.libsession.messaging.opengroups.OpenGroupAPI
import org.session.libsession.messaging.opengroups.OpenGroupMessage import org.session.libsession.messaging.opengroups.OpenGroupMessage
import org.session.libsession.messaging.utilities.MessageWrapper import org.session.libsession.messaging.utilities.MessageWrapper
import org.session.libsession.snode.RawResponsePromise import org.session.libsession.snode.RawResponsePromise
import org.session.libsession.snode.SnodeAPI import org.session.libsession.snode.SnodeAPI
import org.session.libsession.snode.SnodeMessage import org.session.libsession.snode.SnodeMessage
import org.session.libsession.utilities.SSKEnvironment
import org.session.libsignal.libsignal.logging.Log import org.session.libsignal.libsignal.logging.Log
import org.session.libsignal.service.api.messages.SignalServiceAttachment import org.session.libsignal.service.api.messages.SignalServiceAttachment
import org.session.libsignal.service.internal.push.SignalServiceProtos import org.session.libsignal.service.internal.push.SignalServiceProtos
@ -215,7 +214,6 @@ object MessageSender {
// Open Groups // Open Groups
fun sendToOpenGroupDestination(destination: Destination, message: Message): Promise<Unit, Exception> { fun sendToOpenGroupDestination(destination: Destination, message: Message): Promise<Unit, Exception> {
val deferred = deferred<Unit, Exception>() val deferred = deferred<Unit, Exception>()
val promise = deferred.promise
val storage = MessagingConfiguration.shared.storage val storage = MessagingConfiguration.shared.storage
val preconditionFailure = Exception("Destination should not be contacts or closed groups!") val preconditionFailure = Exception("Destination should not be contacts or closed groups!")
message.sentTimestamp ?: run { message.sentTimestamp = System.currentTimeMillis() } message.sentTimestamp ?: run { message.sentTimestamp = System.currentTimeMillis() }
@ -233,7 +231,7 @@ object MessageSender {
} }
} }
// Set the failure handler (need it here already for precondition failure handling) // Set the failure handler (need it here already for precondition failure handling)
fun handleFailure(error: Exception,) { fun handleFailure(error: Exception) {
handleFailedMessageSend(message, error) handleFailedMessageSend(message, error)
deferred.reject(error) deferred.reject(error)
} }
@ -263,8 +261,14 @@ object MessageSender {
// Result Handling // Result Handling
fun handleSuccessfulMessageSend(message: Message, destination: Destination) { fun handleSuccessfulMessageSend(message: Message, destination: Destination) {
MessagingConfiguration.shared.storage.insertMessageOutbox(message) val storage = MessagingConfiguration.shared.storage
// TODO val messageId = storage.getMessageIdInDatabase(message.sentTimestamp!!, message.sender!!) ?: return
if (message.openGroupServerMessageID != null) {
storage.setOpenGroupServerMessageID(messageId, message.openGroupServerMessageID!!)
}
storage.markAsSent(messageId)
storage.markUnidentified(messageId)
SSKEnvironment.shared.messageExpirationManager.startAnyExpiration(messageId)
} }
fun handleFailedMessageSend(message: Message, error: Exception) { fun handleFailedMessageSend(message: Message, error: Exception) {

View File

@ -34,6 +34,7 @@ class SSKEnvironment(
interface MessageExpirationManagerProtocol { interface MessageExpirationManagerProtocol {
fun setExpirationTimer(messageID: Long?, duration: Int, senderPublicKey: String, content: SignalServiceProtos.Content) fun setExpirationTimer(messageID: Long?, duration: Int, senderPublicKey: String, content: SignalServiceProtos.Content)
fun disableExpirationTimer(messageID: Long?, senderPublicKey: String, content: SignalServiceProtos.Content) fun disableExpirationTimer(messageID: Long?, senderPublicKey: String, content: SignalServiceProtos.Content)
fun startAnyExpiration(messageID: Long)
} }
companion object { companion object {