From f3c3483cdeb7cf5e9ac6c04987438c653c400a49 Mon Sep 17 00:00:00 2001 From: Ryan ZHAO Date: Wed, 20 Jan 2021 16:29:52 +1100 Subject: [PATCH] complete message sender --- .../securesms/database/MmsSmsDatabase.java | 9 +++++ .../securesms/database/Storage.kt | 34 ++++++++++++++++--- .../service/ExpiringMessageManager.java | 15 ++++++++ .../libsession/messaging/StorageProtocol.kt | 9 +++-- .../libsession/messaging/messages/Message.kt | 2 +- .../MessageReceiverHandler.kt | 10 +++--- .../sending_receiving/MessageSender.kt | 20 ++++++----- .../libsession/utilities/SSKEnvironment.kt | 1 + 8 files changed, 79 insertions(+), 21 deletions(-) diff --git a/app/src/main/java/org/thoughtcrime/securesms/database/MmsSmsDatabase.java b/app/src/main/java/org/thoughtcrime/securesms/database/MmsSmsDatabase.java index 4bd6d03813..dad9fb1860 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/database/MmsSmsDatabase.java +++ b/app/src/main/java/org/thoughtcrime/securesms/database/MmsSmsDatabase.java @@ -78,6 +78,15 @@ public class MmsSmsDatabase extends Database { 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) { MmsSmsDatabase db = DatabaseFactory.getMmsSmsDatabase(context); diff --git a/app/src/main/java/org/thoughtcrime/securesms/database/Storage.kt b/app/src/main/java/org/thoughtcrime/securesms/database/Storage.kt index 66581b7dce..fbc884f209 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/database/Storage.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/database/Storage.kt @@ -253,12 +253,38 @@ class Storage(context: Context, helper: SQLCipherOpenHelper) : Database(context, TODO("Not yet implemented") } - override fun insertMessageOutbox(message: Message) { - TODO("Not yet implemented") + override fun getMessageIdInDatabase(timestamp: Long, author: String): Long? { + val database = DatabaseFactory.getMmsSmsDatabase(context) + val address = Address.fromSerialized(author) + return database.getMessageFor(timestamp, address)?.getId() } - override fun insertMessageInbox(message: Message) { - TODO("Not yet implemented") + override fun setOpenGroupServerMessageID(messageID: Long, serverID: Long) { + 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) { diff --git a/app/src/main/java/org/thoughtcrime/securesms/service/ExpiringMessageManager.java b/app/src/main/java/org/thoughtcrime/securesms/service/ExpiringMessageManager.java index eb478dfa24..6020d091c5 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/service/ExpiringMessageManager.java +++ b/app/src/main/java/org/thoughtcrime/securesms/service/ExpiringMessageManager.java @@ -103,6 +103,21 @@ public class ExpiringMessageManager implements SSKEnvironment.MessageExpirationM 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 { public void run() { SmsDatabase.Reader smsReader = smsDatabase.readerFor(smsDatabase.getExpirationStartedMessages()); diff --git a/libsession/src/main/java/org/session/libsession/messaging/StorageProtocol.kt b/libsession/src/main/java/org/session/libsession/messaging/StorageProtocol.kt index cf478a8b23..6bde0bbbca 100644 --- a/libsession/src/main/java/org/session/libsession/messaging/StorageProtocol.kt +++ b/libsession/src/main/java/org/session/libsession/messaging/StorageProtocol.kt @@ -87,13 +87,16 @@ interface StorageProtocol { fun addReceivedMessageTimestamp(timestamp: Long) // Returns the IDs of the saved attachments. fun persist(attachments: List): List - 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) // Closed Groups fun getGroup(groupID: String): GroupRecord? - fun createGroup(groupId: String, title: String?, members: List
, avatar: SignalServiceAttachmentPointer?, relay: String?, admins: List
) + fun createGroup(groupID: String, title: String?, members: List
, avatar: SignalServiceAttachmentPointer?, relay: String?, admins: List
) fun setActive(groupID: String, value: Boolean) fun removeMember(groupID: String, member: Address) fun updateMembers(groupID: String, members: List
) diff --git a/libsession/src/main/java/org/session/libsession/messaging/messages/Message.kt b/libsession/src/main/java/org/session/libsession/messaging/messages/Message.kt index 02ee61a1c2..87dd17bf9f 100644 --- a/libsession/src/main/java/org/session/libsession/messaging/messages/Message.kt +++ b/libsession/src/main/java/org/session/libsession/messaging/messages/Message.kt @@ -4,7 +4,7 @@ import org.session.libsignal.service.internal.push.SignalServiceProtos abstract class Message { - var id: String? = null + var id: Long? = null var threadID: Long? = null var sentTimestamp: Long? = null var receivedTimestamp: Long? = null diff --git a/libsession/src/main/java/org/session/libsession/messaging/sending_receiving/MessageReceiverHandler.kt b/libsession/src/main/java/org/session/libsession/messaging/sending_receiving/MessageReceiverHandler.kt index a9d4006d4e..be294b8246 100644 --- a/libsession/src/main/java/org/session/libsession/messaging/sending_receiving/MessageReceiverHandler.kt +++ b/libsession/src/main/java/org/session/libsession/messaging/sending_receiving/MessageReceiverHandler.kt @@ -70,21 +70,21 @@ fun MessageReceiver.showTypingIndicatorIfNeeded(senderPublicKey: String) { val context = MessagingConfiguration.shared.context val address = Address.fromSerialized(senderPublicKey) 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) { val context = MessagingConfiguration.shared.context val address = Address.fromSerialized(senderPublicKey) 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) { val context = MessagingConfiguration.shared.context val address = Address.fromSerialized(senderPublicKey) 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) { @@ -96,14 +96,14 @@ private fun MessageReceiver.handleExpirationTimerUpdate(message: ExpirationTimer } fun MessageReceiver.setExpirationTimer(message: ExpirationTimerUpdate, proto: SignalServiceProtos.Content) { - val id = message.id?.toLong() + val id = message.id val duration = message.duration!! val senderPublicKey = message.sender!! SSKEnvironment.shared.messageExpirationManager.setExpirationTimer(id, duration, senderPublicKey, proto) } fun MessageReceiver.disableExpirationTimer(message: ExpirationTimerUpdate, proto: SignalServiceProtos.Content) { - val id = message.id?.toLong() + val id = message.id val senderPublicKey = message.sender!! SSKEnvironment.shared.messageExpirationManager.disableExpirationTimer(id, senderPublicKey, proto) } diff --git a/libsession/src/main/java/org/session/libsession/messaging/sending_receiving/MessageSender.kt b/libsession/src/main/java/org/session/libsession/messaging/sending_receiving/MessageSender.kt index 69a1846516..bfaaad0eea 100644 --- a/libsession/src/main/java/org/session/libsession/messaging/sending_receiving/MessageSender.kt +++ b/libsession/src/main/java/org/session/libsession/messaging/sending_receiving/MessageSender.kt @@ -3,23 +3,22 @@ package org.session.libsession.messaging.sending_receiving import android.util.Size import nl.komponents.kovenant.Promise import nl.komponents.kovenant.deferred - import org.session.libsession.messaging.MessagingConfiguration 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.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.visible.Attachment 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.OpenGroupMessage import org.session.libsession.messaging.utilities.MessageWrapper import org.session.libsession.snode.RawResponsePromise import org.session.libsession.snode.SnodeAPI import org.session.libsession.snode.SnodeMessage - +import org.session.libsession.utilities.SSKEnvironment import org.session.libsignal.libsignal.logging.Log import org.session.libsignal.service.api.messages.SignalServiceAttachment import org.session.libsignal.service.internal.push.SignalServiceProtos @@ -215,7 +214,6 @@ object MessageSender { // Open Groups fun sendToOpenGroupDestination(destination: Destination, message: Message): Promise { val deferred = deferred() - val promise = deferred.promise val storage = MessagingConfiguration.shared.storage val preconditionFailure = Exception("Destination should not be contacts or closed groups!") 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) - fun handleFailure(error: Exception,) { + fun handleFailure(error: Exception) { handleFailedMessageSend(message, error) deferred.reject(error) } @@ -263,8 +261,14 @@ object MessageSender { // Result Handling fun handleSuccessfulMessageSend(message: Message, destination: Destination) { - MessagingConfiguration.shared.storage.insertMessageOutbox(message) - // TODO + val storage = MessagingConfiguration.shared.storage + 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) { diff --git a/libsession/src/main/java/org/session/libsession/utilities/SSKEnvironment.kt b/libsession/src/main/java/org/session/libsession/utilities/SSKEnvironment.kt index b522225543..eb9635a9c3 100644 --- a/libsession/src/main/java/org/session/libsession/utilities/SSKEnvironment.kt +++ b/libsession/src/main/java/org/session/libsession/utilities/SSKEnvironment.kt @@ -34,6 +34,7 @@ class SSKEnvironment( interface MessageExpirationManagerProtocol { fun setExpirationTimer(messageID: Long?, duration: Int, senderPublicKey: String, content: SignalServiceProtos.Content) fun disableExpirationTimer(messageID: Long?, senderPublicKey: String, content: SignalServiceProtos.Content) + fun startAnyExpiration(messageID: Long) } companion object {