From d9eaedd6ae8332459236c2225e8558121698abe3 Mon Sep 17 00:00:00 2001 From: Ryan ZHAO Date: Tue, 2 Mar 2021 12:24:09 +1100 Subject: [PATCH] hook up sending pipeline & clean --- .../securesms/ApplicationContext.java | 2 + .../securesms/MessageDetailsActivity.java | 31 ++- .../thoughtcrime/securesms/ShareActivity.java | 3 +- .../attachments/DatabaseAttachmentProvider.kt | 3 +- .../MmsNotificationAttachment.java | 7 +- .../securesms/components/DocumentView.java | 4 +- .../securesms/components/ThumbnailView.java | 5 +- .../components/TransferControlView.java | 15 +- .../conversation/ConversationActivity.java | 136 ++++++----- .../conversation/ConversationFragment.java | 33 ++- .../conversation/ConversationItem.java | 5 +- .../database/AttachmentDatabase.java | 46 +--- .../securesms/database/MessagingDatabase.java | 27 +-- .../securesms/database/MmsDatabase.java | 10 +- .../securesms/database/SmsDatabase.java | 13 +- .../securesms/database/Storage.kt | 17 +- .../securesms/database/ThreadDatabase.java | 9 +- .../database/helpers/SQLCipherOpenHelper.java | 9 +- .../database/model/MediaMmsMessageRecord.java | 4 +- .../database/model/MessageRecord.java | 24 +- .../database/model/MmsMessageRecord.java | 4 +- .../model/NotificationMmsMessageRecord.java | 4 +- .../securesms/database/model/Quote.java | 5 + .../database/model/SmsMessageRecord.java | 2 +- .../securesms/groups/GroupManager.java | 93 +------- .../securesms/jobs/AttachmentDownloadJob.java | 9 +- .../securesms/jobs/PushDecryptJob.java | 10 +- .../securesms/jobs/PushGroupSendJob.java | 4 +- .../linkpreview/LinkPreviewRepository.java | 3 +- .../linkpreview/LinkPreviewViewModel.java | 6 +- .../activities/CreateClosedGroupActivity.kt | 5 +- .../activities/CreatePrivateChatActivity.kt | 3 +- .../activities/EditClosedGroupActivity.kt | 2 - .../loki/activities/QRCodeActivity.kt | 3 +- .../loki/database/SessionJobDatabase.kt | 2 +- .../loki/protocol/ClosedGroupsProtocolV2.kt | 4 +- .../securesms/loki/views/MessageAudioView.kt | 3 +- .../securesms/mms/AudioSlide.java | 3 +- .../mms/OutgoingExpirationUpdateMessage.java | 4 +- .../mms/OutgoingGroupMediaMessage.java | 8 +- .../securesms/mms/OutgoingMediaMessage.java | 21 +- .../org/thoughtcrime/securesms/mms/Slide.java | 8 +- .../AndroidAutoReplyReceiver.java | 31 ++- .../notifications/RemoteReplyReceiver.java | 26 ++- .../service/ExpiringMessageManager.java | 11 +- .../service/QuickResponseService.java | 16 +- .../securesms/sms/MessageSender.java | 213 ------------------ .../sms/OutgoingEncryptedMessage.java | 15 -- .../database/documents/Document.java | 2 +- .../documents/IdentityKeyMismatch.java | 2 +- .../documents/IdentityKeyMismatchList.java | 2 +- .../database/documents/NetworkFailure.java | 2 +- .../documents/NetworkFailureList.java | 2 +- .../libsession/messaging/StorageProtocol.kt | 4 +- .../messaging/jobs/AttachmentUploadJob.kt | 2 +- .../messaging/jobs/MessageReceiveJob.kt | 4 +- .../messaging/jobs/MessageSendJob.kt | 2 +- .../libsession/messaging/messages/Message.kt | 8 +- .../messages/control/ExpirationTimerUpdate.kt | 3 +- .../signal}/IncomingEncryptedMessage.java | 2 +- .../signal}/IncomingGroupMessage.java | 2 +- .../messages/signal}/IncomingTextMessage.java | 8 +- .../messages/signal}/OutgoingTextMessage.java | 13 +- .../messaging/messages/visible/Attachment.kt | 4 +- .../messaging/messages/visible/LinkPreview.kt | 9 + .../messaging/messages/visible/Quote.kt | 11 + .../messages/visible/VisibleMessage.kt | 10 + .../sending_receiving/MessageSender.kt | 94 +++++--- .../MessageSenderConvenience.kt | 38 ---- .../attachments/AttachmentId.java | 4 +- .../sending_receiving/pollers/Poller.kt | 2 +- .../messaging/threads/DistributionTypes.kt | 9 + .../libsession/snode/OnionRequestAPI.kt | 4 +- .../org/session/libsession/snode/Snode.kt | 2 +- .../org/session/libsession/snode/SnodeAPI.kt | 23 +- .../libsession/snode/SnodeConfiguration.kt | 5 +- .../libsession/utilities/SSKEnvironment.kt | 2 +- .../api/messages/SendMessageResult.java | 8 - .../libsignal/service/loki/api/Snode.kt | 2 +- 79 files changed, 457 insertions(+), 749 deletions(-) delete mode 100644 app/src/main/java/org/thoughtcrime/securesms/sms/MessageSender.java delete mode 100644 app/src/main/java/org/thoughtcrime/securesms/sms/OutgoingEncryptedMessage.java rename {app/src/main/java/org/thoughtcrime/securesms => libsession/src/main/java/org/session/libsession}/database/documents/Document.java (66%) rename {app/src/main/java/org/thoughtcrime/securesms => libsession/src/main/java/org/session/libsession}/database/documents/IdentityKeyMismatch.java (98%) rename {app/src/main/java/org/thoughtcrime/securesms => libsession/src/main/java/org/session/libsession}/database/documents/IdentityKeyMismatchList.java (93%) rename {app/src/main/java/org/thoughtcrime/securesms => libsession/src/main/java/org/session/libsession}/database/documents/NetworkFailure.java (93%) rename {app/src/main/java/org/thoughtcrime/securesms => libsession/src/main/java/org/session/libsession}/database/documents/NetworkFailureList.java (92%) rename {app/src/main/java/org/thoughtcrime/securesms/sms => libsession/src/main/java/org/session/libsession/messaging/messages/signal}/IncomingEncryptedMessage.java (81%) rename {app/src/main/java/org/thoughtcrime/securesms/sms => libsession/src/main/java/org/session/libsession/messaging/messages/signal}/IncomingGroupMessage.java (91%) rename {app/src/main/java/org/thoughtcrime/securesms/sms => libsession/src/main/java/org/session/libsession/messaging/messages/signal}/IncomingTextMessage.java (96%) rename {app/src/main/java/org/thoughtcrime/securesms/sms => libsession/src/main/java/org/session/libsession/messaging/messages/signal}/OutgoingTextMessage.java (69%) delete mode 100644 libsession/src/main/java/org/session/libsession/messaging/sending_receiving/MessageSenderConvenience.kt create mode 100644 libsession/src/main/java/org/session/libsession/messaging/threads/DistributionTypes.kt diff --git a/app/src/main/java/org/thoughtcrime/securesms/ApplicationContext.java b/app/src/main/java/org/thoughtcrime/securesms/ApplicationContext.java index 78dad49b64..d4a6da8f6f 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/ApplicationContext.java +++ b/app/src/main/java/org/thoughtcrime/securesms/ApplicationContext.java @@ -34,6 +34,7 @@ import com.google.firebase.iid.FirebaseInstanceId; import org.conscrypt.Conscrypt; import org.session.libsession.messaging.MessagingConfiguration; import org.session.libsession.messaging.avatars.AvatarHelper; +import org.session.libsession.snode.SnodeConfiguration; import org.session.libsession.utilities.SSKEnvironment; import org.session.libsession.messaging.sending_receiving.notifications.MessageNotifier; import org.session.libsession.utilities.dynamiclanguage.DynamicLanguageContextWrapper; @@ -176,6 +177,7 @@ public class ApplicationContext extends MultiDexApplication implements Dependenc DatabaseFactory.getStorage(this), DatabaseFactory.getAttachmentProvider(this), new SessionProtocolImpl(this)); + SnodeConfiguration.Companion.configure(apiDB, broadcaster); if (userPublicKey != null) { SwarmAPI.Companion.configureIfNeeded(apiDB); SnodeAPI.Companion.configureIfNeeded(userPublicKey, apiDB, broadcaster); diff --git a/app/src/main/java/org/thoughtcrime/securesms/MessageDetailsActivity.java b/app/src/main/java/org/thoughtcrime/securesms/MessageDetailsActivity.java index 988890ae05..f78c899974 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/MessageDetailsActivity.java +++ b/app/src/main/java/org/thoughtcrime/securesms/MessageDetailsActivity.java @@ -37,7 +37,11 @@ import androidx.loader.app.LoaderManager.LoaderCallbacks; import androidx.loader.content.Loader; - +import org.session.libsession.messaging.messages.visible.LinkPreview; +import org.session.libsession.messaging.messages.visible.Quote; +import org.session.libsession.messaging.messages.visible.VisibleMessage; +import org.session.libsession.messaging.sending_receiving.MessageSender; +import org.session.libsession.messaging.sending_receiving.attachments.Attachment; import org.thoughtcrime.securesms.MessageDetailsRecipientAdapter.RecipientDeliveryStatus; import org.session.libsession.utilities.color.MaterialColor; import org.thoughtcrime.securesms.conversation.ConversationItem; @@ -50,12 +54,12 @@ import org.thoughtcrime.securesms.database.SmsDatabase; import org.thoughtcrime.securesms.database.loaders.MessageDetailsLoader; import org.thoughtcrime.securesms.database.model.MessageRecord; import org.session.libsignal.utilities.logging.Log; +import org.thoughtcrime.securesms.database.model.MmsMessageRecord; import org.thoughtcrime.securesms.loki.database.LokiMessageDatabase; import org.thoughtcrime.securesms.mms.GlideApp; import org.thoughtcrime.securesms.mms.GlideRequests; import org.session.libsession.messaging.threads.recipients.Recipient; import org.session.libsession.messaging.threads.recipients.RecipientModifiedListener; -import org.thoughtcrime.securesms.sms.MessageSender; import org.thoughtcrime.securesms.util.DateUtils; import org.session.libsession.utilities.ExpirationUtil; import org.session.libsession.utilities.Util; @@ -441,7 +445,28 @@ public class MessageDetailsActivity extends PassphraseRequiredActionBarActivity } private void onResendClicked(View v) { - MessageSender.resend(MessageDetailsActivity.this, messageRecord); + Recipient recipient = messageRecord.getRecipient(); + VisibleMessage message = new VisibleMessage(); + message.setId(messageRecord.getId()); + message.setText(messageRecord.getBody()); + message.setSentTimestamp(messageRecord.getTimestamp()); + if (recipient.isGroupRecipient()) { + message.setGroupPublicKey(recipient.getAddress().toGroupString()); + } else { + message.setRecipient(messageRecord.getRecipient().getAddress().serialize()); + } + message.setThreadID(messageRecord.getThreadId()); + if (messageRecord.isMms()) { + MmsMessageRecord mmsMessageRecord = (MmsMessageRecord) messageRecord; + if (!mmsMessageRecord.getLinkPreviews().isEmpty()) { + message.setLinkPreview(LinkPreview.Companion.from(mmsMessageRecord.getLinkPreviews().get(0))); + } + if (mmsMessageRecord.getQuote() != null) { + message.setQuote(Quote.Companion.from(mmsMessageRecord.getQuote().getQuoteModel())); + } + message.addSignalAttachments(mmsMessageRecord.getSlideDeck().asAttachments()); + } + MessageSender.send(message, recipient.getAddress()); resendButton.setVisibility(View.GONE); } } diff --git a/app/src/main/java/org/thoughtcrime/securesms/ShareActivity.java b/app/src/main/java/org/thoughtcrime/securesms/ShareActivity.java index 193ebb2fe5..9c873eb6db 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/ShareActivity.java +++ b/app/src/main/java/org/thoughtcrime/securesms/ShareActivity.java @@ -35,6 +35,7 @@ import androidx.annotation.Nullable; import androidx.appcompat.app.ActionBar; import androidx.appcompat.widget.Toolbar; +import org.session.libsession.messaging.threads.DistributionTypes; import org.thoughtcrime.securesms.components.SearchToolbar; import org.thoughtcrime.securesms.conversation.ConversationActivity; import org.session.libsession.messaging.threads.Address; @@ -249,7 +250,7 @@ public class ShareActivity extends PassphraseRequiredActionBarActivity public void onContactSelected(String number) { Recipient recipient = Recipient.from(this, Address.fromExternal(this, number), true); long existingThread = DatabaseFactory.getThreadDatabase(this).getThreadIdIfExistsFor(recipient); - createConversation(existingThread, recipient.getAddress(), ThreadDatabase.DistributionTypes.DEFAULT); + createConversation(existingThread, recipient.getAddress(), DistributionTypes.DEFAULT); } @Override diff --git a/app/src/main/java/org/thoughtcrime/securesms/attachments/DatabaseAttachmentProvider.kt b/app/src/main/java/org/thoughtcrime/securesms/attachments/DatabaseAttachmentProvider.kt index b1b1cdab4e..bfb226d002 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/attachments/DatabaseAttachmentProvider.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/attachments/DatabaseAttachmentProvider.kt @@ -79,7 +79,8 @@ class DatabaseAttachmentProvider(context: Context, helper: SQLCipherOpenHelper) override fun isOutgoingMessage(timestamp: Long): Boolean { val smsDatabase = DatabaseFactory.getSmsDatabase(context) - return smsDatabase.isOutgoingMessage(timestamp) + val mmsDatabase = DatabaseFactory.getMmsDatabase(context) + return smsDatabase.isOutgoingMessage(timestamp) || mmsDatabase.isOutgoingMessage(timestamp) } override fun getMessageID(serverID: Long): Long? { diff --git a/app/src/main/java/org/thoughtcrime/securesms/attachments/MmsNotificationAttachment.java b/app/src/main/java/org/thoughtcrime/securesms/attachments/MmsNotificationAttachment.java index a68cf58db9..46dd4367f1 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/attachments/MmsNotificationAttachment.java +++ b/app/src/main/java/org/thoughtcrime/securesms/attachments/MmsNotificationAttachment.java @@ -4,6 +4,7 @@ package org.thoughtcrime.securesms.attachments; import android.net.Uri; import androidx.annotation.Nullable; +import org.session.libsession.messaging.sending_receiving.attachments.AttachmentTransferProgress; import org.thoughtcrime.securesms.database.AttachmentDatabase; import org.thoughtcrime.securesms.database.MmsDatabase; import org.session.libsession.messaging.sending_receiving.attachments.Attachment; @@ -30,11 +31,11 @@ public class MmsNotificationAttachment extends Attachment { if (status == MmsDatabase.Status.DOWNLOAD_INITIALIZED || status == MmsDatabase.Status.DOWNLOAD_NO_CONNECTIVITY) { - return AttachmentDatabase.TRANSFER_PROGRESS_PENDING; + return AttachmentTransferProgress.TRANSFER_PROGRESS_PENDING; } else if (status == MmsDatabase.Status.DOWNLOAD_CONNECTING) { - return AttachmentDatabase.TRANSFER_PROGRESS_STARTED; + return AttachmentTransferProgress.TRANSFER_PROGRESS_STARTED; } else { - return AttachmentDatabase.TRANSFER_PROGRESS_FAILED; + return AttachmentTransferProgress.TRANSFER_PROGRESS_FAILED; } } } diff --git a/app/src/main/java/org/thoughtcrime/securesms/components/DocumentView.java b/app/src/main/java/org/thoughtcrime/securesms/components/DocumentView.java index 3627572054..1301fa7286 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/components/DocumentView.java +++ b/app/src/main/java/org/thoughtcrime/securesms/components/DocumentView.java @@ -20,6 +20,8 @@ import com.pnikosis.materialishprogress.ProgressWheel; import org.greenrobot.eventbus.Subscribe; import org.greenrobot.eventbus.ThreadMode; import network.loki.messenger.R; + +import org.session.libsession.messaging.sending_receiving.attachments.AttachmentTransferProgress; import org.thoughtcrime.securesms.database.AttachmentDatabase; import org.thoughtcrime.securesms.events.PartProgressEvent; import org.thoughtcrime.securesms.mms.DocumentSlide; @@ -94,7 +96,7 @@ public class DocumentView extends FrameLayout { controlToggle.displayQuick(downloadButton); downloadButton.setOnClickListener(new DownloadClickedListener(documentSlide)); if (downloadProgress.isSpinning()) downloadProgress.stopSpinning(); - } else if (showControls && documentSlide.getTransferState() == AttachmentDatabase.TRANSFER_PROGRESS_STARTED) { + } else if (showControls && documentSlide.getTransferState() == AttachmentTransferProgress.TRANSFER_PROGRESS_STARTED) { controlToggle.displayQuick(downloadProgress); downloadProgress.spin(); } else { diff --git a/app/src/main/java/org/thoughtcrime/securesms/components/ThumbnailView.java b/app/src/main/java/org/thoughtcrime/securesms/components/ThumbnailView.java index 2340df43c3..2628f031dc 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/components/ThumbnailView.java +++ b/app/src/main/java/org/thoughtcrime/securesms/components/ThumbnailView.java @@ -7,6 +7,7 @@ import androidx.annotation.NonNull; import androidx.annotation.UiThread; import android.util.AttributeSet; +import org.session.libsession.messaging.sending_receiving.attachments.AttachmentTransferProgress; import org.session.libsignal.utilities.logging.Log; import android.view.View; import android.view.ViewGroup; @@ -248,7 +249,7 @@ public class ThumbnailView extends FrameLayout { } if (slide.getThumbnailUri() != null && slide.hasPlayOverlay() && - (slide.getTransferState() == AttachmentDatabase.TRANSFER_PROGRESS_DONE || isPreview)) + (slide.getTransferState() == AttachmentTransferProgress.TRANSFER_PROGRESS_DONE || isPreview)) { this.playOverlay.setVisibility(View.VISIBLE); } else { @@ -402,7 +403,7 @@ public class ThumbnailView extends FrameLayout { if (thumbnailClickListener != null && slide != null && slide.asAttachment().getDataUri() != null && - slide.getTransferState() == AttachmentDatabase.TRANSFER_PROGRESS_DONE) + slide.getTransferState() == AttachmentTransferProgress.TRANSFER_PROGRESS_DONE) { thumbnailClickListener.onClick(view, slide); } else if (parentClickListener != null) { diff --git a/app/src/main/java/org/thoughtcrime/securesms/components/TransferControlView.java b/app/src/main/java/org/thoughtcrime/securesms/components/TransferControlView.java index 5828641dc0..36a607c819 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/components/TransferControlView.java +++ b/app/src/main/java/org/thoughtcrime/securesms/components/TransferControlView.java @@ -17,6 +17,7 @@ import org.greenrobot.eventbus.EventBus; import org.greenrobot.eventbus.Subscribe; import org.greenrobot.eventbus.ThreadMode; import org.session.libsession.messaging.sending_receiving.attachments.Attachment; +import org.session.libsession.messaging.sending_receiving.attachments.AttachmentTransferProgress; import org.thoughtcrime.securesms.database.AttachmentDatabase; import org.thoughtcrime.securesms.events.PartProgressEvent; import org.thoughtcrime.securesms.mms.Slide; @@ -105,17 +106,17 @@ public class TransferControlView extends FrameLayout { } for (Slide slide : slides) { - if (slide.asAttachment().getTransferState() == AttachmentDatabase.TRANSFER_PROGRESS_DONE) { + if (slide.asAttachment().getTransferState() == AttachmentTransferProgress.TRANSFER_PROGRESS_DONE) { downloadProgress.put(slide.asAttachment(), 1f); } } switch (getTransferState(slides)) { - case AttachmentDatabase.TRANSFER_PROGRESS_STARTED: + case AttachmentTransferProgress.TRANSFER_PROGRESS_STARTED: showProgressSpinner(calculateProgress(downloadProgress)); break; - case AttachmentDatabase.TRANSFER_PROGRESS_PENDING: - case AttachmentDatabase.TRANSFER_PROGRESS_FAILED: + case AttachmentTransferProgress.TRANSFER_PROGRESS_PENDING: + case AttachmentTransferProgress.TRANSFER_PROGRESS_FAILED: downloadDetailsText.setText(getDownloadText(this.slides)); display(downloadDetails); break; @@ -174,9 +175,9 @@ public class TransferControlView extends FrameLayout { } private int getTransferState(@NonNull List slides) { - int transferState = AttachmentDatabase.TRANSFER_PROGRESS_DONE; + int transferState = AttachmentTransferProgress.TRANSFER_PROGRESS_DONE; for (Slide slide : slides) { - if (slide.getTransferState() == AttachmentDatabase.TRANSFER_PROGRESS_PENDING && transferState == AttachmentDatabase.TRANSFER_PROGRESS_DONE) { + if (slide.getTransferState() == AttachmentTransferProgress.TRANSFER_PROGRESS_PENDING && transferState == AttachmentTransferProgress.TRANSFER_PROGRESS_DONE) { transferState = slide.getTransferState(); } else { transferState = Math.max(transferState, slide.getTransferState()); @@ -189,7 +190,7 @@ public class TransferControlView extends FrameLayout { if (slides.size() == 1) { return slides.get(0).getContentDescription(); } else { - int downloadCount = Stream.of(slides).reduce(0, (count, slide) -> slide.getTransferState() != AttachmentDatabase.TRANSFER_PROGRESS_DONE ? count + 1 : count); + int downloadCount = Stream.of(slides).reduce(0, (count, slide) -> slide.getTransferState() != AttachmentTransferProgress.TRANSFER_PROGRESS_DONE ? count + 1 : count); return getContext().getResources().getQuantityString(R.plurals.TransferControlView_n_items, downloadCount, downloadCount); } } diff --git a/app/src/main/java/org/thoughtcrime/securesms/conversation/ConversationActivity.java b/app/src/main/java/org/thoughtcrime/securesms/conversation/ConversationActivity.java index 58727424ba..c0527b4dc2 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/conversation/ConversationActivity.java +++ b/app/src/main/java/org/thoughtcrime/securesms/conversation/ConversationActivity.java @@ -85,6 +85,10 @@ import org.greenrobot.eventbus.Subscribe; import org.greenrobot.eventbus.ThreadMode; +import org.session.libsession.messaging.messages.control.ExpirationTimerUpdate; +import org.session.libsession.messaging.messages.visible.VisibleMessage; +import org.session.libsession.messaging.sending_receiving.attachments.Attachment; +import org.session.libsession.messaging.threads.DistributionTypes; import org.session.libsession.utilities.GroupUtil; import org.session.libsession.utilities.MediaTypes; import org.session.libsignal.libsignal.InvalidMessageException; @@ -124,6 +128,7 @@ import org.thoughtcrime.securesms.database.DraftDatabase.Draft; import org.thoughtcrime.securesms.database.DraftDatabase.Drafts; import org.thoughtcrime.securesms.database.MessagingDatabase.MarkedMessageInfo; import org.thoughtcrime.securesms.database.MmsSmsColumns.Types; +import org.thoughtcrime.securesms.database.Storage; import org.thoughtcrime.securesms.database.ThreadDatabase; import org.thoughtcrime.securesms.database.model.MessageRecord; import org.thoughtcrime.securesms.database.model.MmsMessageRecord; @@ -153,7 +158,7 @@ import org.thoughtcrime.securesms.mms.GlideApp; import org.thoughtcrime.securesms.mms.GlideRequests; import org.thoughtcrime.securesms.mms.ImageSlide; import org.thoughtcrime.securesms.mms.MediaConstraints; -import org.thoughtcrime.securesms.mms.OutgoingExpirationUpdateMessage; +import org.thoughtcrime.securesms.mms.MmsException; import org.thoughtcrime.securesms.mms.OutgoingMediaMessage; import org.thoughtcrime.securesms.mms.OutgoingSecureMediaMessage; import org.thoughtcrime.securesms.mms.QuoteId; @@ -168,9 +173,8 @@ import org.session.libsession.messaging.threads.recipients.Recipient; import org.session.libsession.messaging.threads.recipients.RecipientFormattingException; import org.session.libsession.messaging.threads.recipients.RecipientModifiedListener; import org.thoughtcrime.securesms.search.model.MessageResult; -import org.thoughtcrime.securesms.sms.MessageSender; -import org.thoughtcrime.securesms.sms.OutgoingEncryptedMessage; -import org.thoughtcrime.securesms.sms.OutgoingTextMessage; +import org.session.libsession.messaging.sending_receiving.MessageSender; +import org.session.libsession.messaging.messages.signal.OutgoingTextMessage; import org.thoughtcrime.securesms.util.BitmapUtil; import org.thoughtcrime.securesms.util.DateUtils; import org.thoughtcrime.securesms.util.MediaUtil; @@ -197,7 +201,6 @@ import java.util.Collections; import java.util.Date; import java.util.List; import java.util.Locale; -import java.util.Set; import java.util.concurrent.ExecutionException; import java.util.concurrent.atomic.AtomicBoolean; import java.util.concurrent.atomic.AtomicInteger; @@ -571,16 +574,11 @@ public class ConversationActivity extends PassphraseRequiredActionBarActivity final Context context = ConversationActivity.this.getApplicationContext(); - sendMediaMessage(false, - message, + sendMediaMessage(message, slideDeck, inputPanel.getQuote().orNull(), - Collections.emptyList(), - Collections.emptyList(), - expiresIn, - subscriptionId, - initiating, - true).addListener(new AssertedSuccessListener() { + Optional.absent(), + initiating).addListener(new AssertedSuccessListener() { @Override public void onSuccess(Void result) { AsyncTask.THREAD_POOL_EXECUTOR.execute(() -> { @@ -648,7 +646,7 @@ public class ConversationActivity extends PassphraseRequiredActionBarActivity if (!isPushGroupConversation()) { inflater.inflate(R.menu.conversation_mms_group_options, menu); - if (distributionType == ThreadDatabase.DistributionTypes.BROADCAST) { + if (distributionType == DistributionTypes.BROADCAST) { menu.findItem(R.id.menu_distribution_broadcast).setChecked(true); } else { menu.findItem(R.id.menu_distribution_conversation).setChecked(true); @@ -808,8 +806,9 @@ public class ConversationActivity extends PassphraseRequiredActionBarActivity @Override protected Void doInBackground(Void... params) { DatabaseFactory.getRecipientDatabase(ConversationActivity.this).setExpireMessages(recipient, expirationTime); - OutgoingExpirationUpdateMessage outgoingMessage = new OutgoingExpirationUpdateMessage(getRecipient(), System.currentTimeMillis(), expirationTime * 1000L); - MessageSender.send(ConversationActivity.this, outgoingMessage, threadId, false, null); + ExpirationTimerUpdate message = new ExpirationTimerUpdate(); + message.setDuration(expirationTime * 1000); + MessageSender.send(message, recipient.getAddress()); return null; } @@ -1040,7 +1039,7 @@ public class ConversationActivity extends PassphraseRequiredActionBarActivity } private void handleDistributionBroadcastEnabled(MenuItem item) { - distributionType = ThreadDatabase.DistributionTypes.BROADCAST; + distributionType = DistributionTypes.BROADCAST; item.setChecked(true); if (threadId != -1) { @@ -1048,7 +1047,7 @@ public class ConversationActivity extends PassphraseRequiredActionBarActivity @Override protected Void doInBackground(Void... params) { DatabaseFactory.getThreadDatabase(ConversationActivity.this) - .setDistributionType(threadId, ThreadDatabase.DistributionTypes.BROADCAST); + .setDistributionType(threadId, DistributionTypes.BROADCAST); return null; } }.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR); @@ -1056,7 +1055,7 @@ public class ConversationActivity extends PassphraseRequiredActionBarActivity } private void handleDistributionConversationEnabled(MenuItem item) { - distributionType = ThreadDatabase.DistributionTypes.CONVERSATION; + distributionType = DistributionTypes.CONVERSATION; item.setChecked(true); if (threadId != -1) { @@ -1064,7 +1063,7 @@ public class ConversationActivity extends PassphraseRequiredActionBarActivity @Override protected Void doInBackground(Void... params) { DatabaseFactory.getThreadDatabase(ConversationActivity.this) - .setDistributionType(threadId, ThreadDatabase.DistributionTypes.CONVERSATION); + .setDistributionType(threadId, DistributionTypes.CONVERSATION); return null; } }.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR); @@ -1335,7 +1334,7 @@ public class ConversationActivity extends PassphraseRequiredActionBarActivity if (address == null) { finish(); return; } recipient = Recipient.from(this, address, true); threadId = getIntent().getLongExtra(THREAD_ID_EXTRA, -1); - distributionType = getIntent().getIntExtra(DISTRIBUTION_TYPE_EXTRA, ThreadDatabase.DistributionTypes.DEFAULT); + distributionType = getIntent().getIntExtra(DISTRIBUTION_TYPE_EXTRA, DistributionTypes.DEFAULT); glideRequests = GlideApp.with(this); recipient.addListener(this); @@ -1483,14 +1482,6 @@ public class ConversationActivity extends PassphraseRequiredActionBarActivity else if (contactData.numbers.size() > 1) selectContactInfo(contactData); } - private void sendSharedContact(List contacts) { - int subscriptionId = -1; - long expiresIn = recipient.getExpireMessages() * 1000L; - boolean initiating = threadId == -1; - - sendMediaMessage(false, "", attachmentManager.buildSlideDeck(), null, contacts, Collections.emptyList(), expiresIn, subscriptionId, initiating, false); - } - private void selectContactInfo(ContactData contactData) { final CharSequence[] numbers = new CharSequence[contactData.numbers.size()]; final CharSequence[] numberItems = new CharSequence[contactData.numbers.size()]; @@ -1735,8 +1726,6 @@ public class ConversationActivity extends PassphraseRequiredActionBarActivity } String message = getMessage(); - int subscriptionId = -1; - long expiresIn = recipient.getExpireMessages() * 1000L; boolean initiating = threadId == -1; boolean needsSplit = message.length() > characterCalculator.calculateCharacters(message).maxPrimaryMessageSize; boolean isMediaMessage = attachmentManager.isAttachmentPresent() || @@ -1747,9 +1736,9 @@ public class ConversationActivity extends PassphraseRequiredActionBarActivity needsSplit; if (isMediaMessage) { - sendMediaMessage(expiresIn, subscriptionId, initiating); + sendMediaMessage(initiating); } else { - sendTextMessage(expiresIn, subscriptionId, initiating); + sendTextMessage(initiating); } } catch (RecipientFormattingException ex) { Log.w(TAG, ex); @@ -1764,23 +1753,18 @@ public class ConversationActivity extends PassphraseRequiredActionBarActivity } } - private void sendMediaMessage(final long expiresIn, final int subscriptionId, boolean initiating) + private void sendMediaMessage(boolean initiating) throws InvalidMessageException { Log.i(TAG, "Sending media message..."); - sendMediaMessage(false, getMessage(), attachmentManager.buildSlideDeck(), inputPanel.getQuote().orNull(), Collections.emptyList(), linkPreviewViewModel.getActiveLinkPreviews(), expiresIn, subscriptionId, initiating, true); + sendMediaMessage(getMessage(), attachmentManager.buildSlideDeck(), inputPanel.getQuote().orNull(), linkPreviewViewModel.getActiveLinkPreview(), initiating); } - private ListenableFuture sendMediaMessage(final boolean forceSms, - String body, + private ListenableFuture sendMediaMessage(String body, SlideDeck slideDeck, QuoteModel quote, - List contacts, - List previews, - final long expiresIn, - final int subscriptionId, - final boolean initiating, - final boolean clearComposeBox) + Optional linkPreview, + final boolean initiating) { Pair> splitMessage = getSplitMessage(body, characterCalculator.calculateCharacters(body).maxPrimaryMessageSize); @@ -1790,7 +1774,12 @@ public class ConversationActivity extends PassphraseRequiredActionBarActivity slideDeck.addSlide(splitMessage.second.get()); } - OutgoingMediaMessage outgoingMessageCandidate = new OutgoingMediaMessage(recipient, slideDeck, body, System.currentTimeMillis(), subscriptionId, expiresIn, distributionType, quote, contacts, previews); + List attachments = slideDeck.asAttachments(); + + VisibleMessage message = new VisibleMessage(); + message.setSentTimestamp(System.currentTimeMillis()); + message.setText(body); + OutgoingMediaMessage outgoingMessageCandidate = OutgoingMediaMessage.from(message, recipient, attachments, quote, linkPreview.orNull()); final SettableFuture future = new SettableFuture<>(); final Context context = getApplicationContext(); @@ -1800,11 +1789,9 @@ public class ConversationActivity extends PassphraseRequiredActionBarActivity outgoingMessage = new OutgoingSecureMediaMessage(outgoingMessageCandidate); ApplicationContext.getInstance(context).getTypingStatusSender().onTypingStopped(threadId); - if (clearComposeBox) { - inputPanel.clearQuote(); - attachmentManager.clear(glideRequests, false); - silentlySetComposeText(""); - } + inputPanel.clearQuote(); + attachmentManager.clear(glideRequests, false); + silentlySetComposeText(""); final long id = fragment.stageOutgoingMessage(outgoingMessage); @@ -1812,43 +1799,54 @@ public class ConversationActivity extends PassphraseRequiredActionBarActivity DatabaseFactory.getRecipientDatabase(context).setProfileSharing(recipient, true); } - long result = MessageSender.send(context, outgoingMessage, threadId, forceSms, () -> fragment.releaseOutgoingMessage(id)); - - sendComplete(result); + try { + long allocatedThreadId; + if (threadId == -1) { + allocatedThreadId = DatabaseFactory.getThreadDatabase(context).getOrCreateThreadIdFor(recipient); + } else { + allocatedThreadId = threadId; + } + DatabaseFactory.getMmsDatabase(context).insertMessageOutbox(outgoingMessage, allocatedThreadId, false, ()->fragment.releaseOutgoingMessage(id)); + MessageSender.send(message, recipient.getAddress(), attachments, quote, linkPreview.orNull()); + sendComplete(allocatedThreadId); + } catch (MmsException e) { + Log.w(TAG, e); + sendComplete(threadId); + } future.set(null); return future; } - private void sendTextMessage(final long expiresIn, final int subscriptionId, final boolean initiatingConversation) + private void sendTextMessage(final boolean initiating) throws InvalidMessageException { final Context context = getApplicationContext(); final String messageBody = getMessage(); - OutgoingTextMessage message; - - message = new OutgoingEncryptedMessage(recipient, messageBody, expiresIn); + VisibleMessage message = new VisibleMessage(); + message.setSentTimestamp(System.currentTimeMillis()); + message.setText(messageBody); + OutgoingTextMessage outgoingTextMessage = OutgoingTextMessage.from(message, recipient); ApplicationContext.getInstance(context).getTypingStatusSender().onTypingStopped(threadId); silentlySetComposeText(""); - final long id = fragment.stageOutgoingMessage(message); + final long id = fragment.stageOutgoingMessage(outgoingTextMessage); - if (initiatingConversation) { + if (initiating) { DatabaseFactory.getRecipientDatabase(context).setProfileSharing(recipient, true); } - long result = MessageSender.send(context, message, threadId, false, () -> fragment.releaseOutgoingMessage(id)); + long allocatedThreadId; + if (threadId == -1) { + allocatedThreadId = DatabaseFactory.getThreadDatabase(context).getOrCreateThreadIdFor(recipient); + } else { + allocatedThreadId = threadId; + } + DatabaseFactory.getSmsDatabase(context).insertMessageOutbox(allocatedThreadId, outgoingTextMessage, false, message.getSentTimestamp(), ()->fragment.releaseOutgoingMessage(id)); + MessageSender.send(message, recipient.getAddress()); - sendComplete(result); - } - - private void showDefaultSmsPrompt() { - new AlertDialog.Builder(this) - .setMessage(R.string.ConversationActivity_signal_cannot_sent_sms_mms_messages_because_it_is_not_your_default_sms_app) - .setNegativeButton(R.string.ConversationActivity_no, (dialog, which) -> dialog.dismiss()) - .setPositiveButton(R.string.ConversationActivity_yes, (dialog, which) -> handleMakeDefaultSms()) - .show(); + sendComplete(allocatedThreadId); } private void updateToggleButtonState() { @@ -1934,7 +1932,7 @@ public class ConversationActivity extends PassphraseRequiredActionBarActivity SlideDeck slideDeck = new SlideDeck(); slideDeck.addSlide(audioSlide); - sendMediaMessage(false, "", slideDeck, inputPanel.getQuote().orNull(), Collections.emptyList(), Collections.emptyList(), expiresIn, subscriptionId, initiating, true).addListener(new AssertedSuccessListener() { + sendMediaMessage("", slideDeck, inputPanel.getQuote().orNull(), Optional.absent(), initiating).addListener(new AssertedSuccessListener() { @Override public void onSuccess(Void nothing) { new AsyncTask() { diff --git a/app/src/main/java/org/thoughtcrime/securesms/conversation/ConversationFragment.java b/app/src/main/java/org/thoughtcrime/securesms/conversation/ConversationFragment.java index 773ea2d97e..8d1df38d23 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/conversation/ConversationFragment.java +++ b/app/src/main/java/org/thoughtcrime/securesms/conversation/ConversationFragment.java @@ -57,6 +57,8 @@ import androidx.recyclerview.widget.RecyclerView.OnScrollListener; import com.annimon.stream.Stream; +import org.session.libsession.messaging.messages.visible.Quote; +import org.session.libsession.messaging.messages.visible.VisibleMessage; import org.thoughtcrime.securesms.ApplicationContext; import org.thoughtcrime.securesms.MessageDetailsActivity; import org.thoughtcrime.securesms.PassphraseRequiredActionBarActivity; @@ -82,8 +84,9 @@ import org.thoughtcrime.securesms.mms.PartAuthority; import org.thoughtcrime.securesms.mms.Slide; import org.thoughtcrime.securesms.permissions.Permissions; import org.session.libsession.messaging.threads.recipients.Recipient; -import org.thoughtcrime.securesms.sms.MessageSender; -import org.thoughtcrime.securesms.sms.OutgoingTextMessage; +import org.session.libsession.messaging.sending_receiving.MessageSender; +import org.session.libsession.messaging.messages.signal.OutgoingTextMessage; +import org.session.libsession.messaging.sending_receiving.linkpreview.LinkPreview; import org.thoughtcrime.securesms.util.CommunicationActions; import org.thoughtcrime.securesms.util.SaveAttachmentTask; import org.thoughtcrime.securesms.util.StickyHeaderDecoration; @@ -92,7 +95,6 @@ import org.session.libsignal.libsignal.util.guava.Optional; import org.session.libsignal.service.loki.api.opengroups.PublicChat; import org.session.libsignal.service.loki.api.opengroups.PublicChatAPI; -import org.session.libsession.messaging.sending_receiving.linkpreview.LinkPreview; import org.session.libsession.utilities.TextSecurePreferences; import org.session.libsession.utilities.Util; import org.session.libsession.utilities.ViewUtil; @@ -696,11 +698,32 @@ public class ConversationFragment extends Fragment } private void handleResendMessage(final MessageRecord message) { - final Context context = getActivity().getApplicationContext(); new AsyncTask() { @Override protected Void doInBackground(MessageRecord... messageRecords) { - MessageSender.resend(context, messageRecords[0]); + MessageRecord messageRecord = messageRecords[0]; + Recipient recipient = messageRecord.getRecipient(); + VisibleMessage message = new VisibleMessage(); + message.setId(messageRecord.getId()); + message.setText(messageRecord.getBody()); + message.setSentTimestamp(messageRecord.getTimestamp()); + if (recipient.isGroupRecipient()) { + message.setGroupPublicKey(recipient.getAddress().toGroupString()); + } else { + message.setRecipient(messageRecord.getRecipient().getAddress().serialize()); + } + message.setThreadID(messageRecord.getThreadId()); + if (messageRecord.isMms()) { + MmsMessageRecord mmsMessageRecord = (MmsMessageRecord) messageRecord; + if (!mmsMessageRecord.getLinkPreviews().isEmpty()) { + message.setLinkPreview(org.session.libsession.messaging.messages.visible.LinkPreview.Companion.from(mmsMessageRecord.getLinkPreviews().get(0))); + } + if (mmsMessageRecord.getQuote() != null) { + message.setQuote(Quote.Companion.from(mmsMessageRecord.getQuote().getQuoteModel())); + } + message.addSignalAttachments(mmsMessageRecord.getSlideDeck().asAttachments()); + } + MessageSender.send(message, recipient.getAddress()); return null; } }.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, message); diff --git a/app/src/main/java/org/thoughtcrime/securesms/conversation/ConversationItem.java b/app/src/main/java/org/thoughtcrime/securesms/conversation/ConversationItem.java index 964e7834d6..650a708e53 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/conversation/ConversationItem.java +++ b/app/src/main/java/org/thoughtcrime/securesms/conversation/ConversationItem.java @@ -53,6 +53,7 @@ import androidx.annotation.Nullable; import com.annimon.stream.Stream; +import org.session.libsession.messaging.sending_receiving.attachments.AttachmentTransferProgress; import org.session.libsignal.libsignal.util.guava.Optional; import org.session.libsignal.service.loki.api.opengroups.PublicChat; import org.session.libsignal.service.loki.api.opengroups.PublicChatAPI; @@ -1003,10 +1004,10 @@ public class ConversationItem extends LinearLayout if (messageRecord.isMms()) { TextSlide slide = ((MmsMessageRecord) messageRecord).getSlideDeck().getTextSlide(); - if (slide != null && slide.asAttachment().getTransferState() == AttachmentDatabase.TRANSFER_PROGRESS_DONE) { + if (slide != null && slide.asAttachment().getTransferState() == AttachmentTransferProgress.TRANSFER_PROGRESS_DONE) { message = getResources().getString(R.string.ConversationItem_read_more); action = () -> eventListener.onMoreTextClicked(conversationRecipient.getAddress(), messageRecord.getId(), messageRecord.isMms()); - } else if (slide != null && slide.asAttachment().getTransferState() == AttachmentDatabase.TRANSFER_PROGRESS_STARTED) { + } else if (slide != null && slide.asAttachment().getTransferState() == AttachmentTransferProgress.TRANSFER_PROGRESS_STARTED) { message = getResources().getString(R.string.ConversationItem_pending); action = () -> {}; } else if (slide != null) { diff --git a/app/src/main/java/org/thoughtcrime/securesms/database/AttachmentDatabase.java b/app/src/main/java/org/thoughtcrime/securesms/database/AttachmentDatabase.java index 7b67856c19..4954d7c4e9 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/database/AttachmentDatabase.java +++ b/app/src/main/java/org/thoughtcrime/securesms/database/AttachmentDatabase.java @@ -38,6 +38,7 @@ import net.sqlcipher.database.SQLiteDatabase; import org.json.JSONArray; import org.json.JSONException; +import org.session.libsession.messaging.sending_receiving.attachments.AttachmentTransferProgress; import org.session.libsession.utilities.MediaTypes; import org.session.libsignal.utilities.logging.Log; @@ -119,11 +120,6 @@ public class AttachmentDatabase extends Database { static final String AUDIO_VISUAL_SAMPLES = "audio_visual_samples"; // Small amount of audio byte samples to visualise the content (e.g. draw waveform). static final String AUDIO_DURATION = "audio_duration"; // Duration of the audio track in milliseconds. - public static final int TRANSFER_PROGRESS_DONE = 0; - public static final int TRANSFER_PROGRESS_STARTED = 1; - public static final int TRANSFER_PROGRESS_PENDING = 2; - public static final int TRANSFER_PROGRESS_FAILED = 3; - private static final String PART_ID_WHERE = ROW_ID + " = ? AND " + UNIQUE_ID + " = ?"; private static final String PART_AUDIO_ONLY_WHERE = CONTENT_TYPE + " LIKE \"audio/%\""; @@ -213,7 +209,7 @@ public class AttachmentDatabase extends Database { { SQLiteDatabase database = databaseHelper.getWritableDatabase(); ContentValues values = new ContentValues(); - values.put(TRANSFER_STATE, TRANSFER_PROGRESS_FAILED); + values.put(TRANSFER_STATE, AttachmentTransferProgress.TRANSFER_PROGRESS_FAILED); database.update(TABLE_NAME, values, PART_ID_WHERE, attachmentId.toStrings()); notifyConversationListeners(DatabaseFactory.getMmsDatabase(context).getThreadIdForMessage(mmsId)); @@ -268,7 +264,7 @@ public class AttachmentDatabase extends Database { Cursor cursor = null; try { - cursor = database.query(TABLE_NAME, PROJECTION, TRANSFER_STATE + " = ?", new String[] {String.valueOf(TRANSFER_PROGRESS_STARTED)}, null, null, null); + cursor = database.query(TABLE_NAME, PROJECTION, TRANSFER_STATE + " = ?", new String[] {String.valueOf(AttachmentTransferProgress.TRANSFER_PROGRESS_STARTED)}, null, null, null); while (cursor != null && cursor.moveToNext()) { attachments.addAll(getAttachment(cursor)); } @@ -372,7 +368,7 @@ public class AttachmentDatabase extends Database { values.put(DATA_RANDOM, dataInfo.random); } - values.put(TRANSFER_STATE, TRANSFER_PROGRESS_DONE); + values.put(TRANSFER_STATE, AttachmentTransferProgress.TRANSFER_PROGRESS_DONE); values.put(CONTENT_LOCATION, (String)null); values.put(CONTENT_DISPOSITION, (String)null); values.put(DIGEST, (byte[])null); @@ -395,7 +391,7 @@ public class AttachmentDatabase extends Database { SQLiteDatabase database = databaseHelper.getWritableDatabase(); ContentValues values = new ContentValues(); - values.put(TRANSFER_STATE, TRANSFER_PROGRESS_DONE); + values.put(TRANSFER_STATE, AttachmentTransferProgress.TRANSFER_PROGRESS_DONE); values.put(CONTENT_LOCATION, attachment.getLocation()); values.put(DIGEST, attachment.getDigest()); values.put(CONTENT_DISPOSITION, attachment.getKey()); @@ -411,7 +407,7 @@ public class AttachmentDatabase extends Database { SQLiteDatabase database = databaseHelper.getWritableDatabase(); ContentValues values = new ContentValues(); - values.put(TRANSFER_STATE, TRANSFER_PROGRESS_FAILED); + values.put(TRANSFER_STATE, AttachmentTransferProgress.TRANSFER_PROGRESS_FAILED); database.update(TABLE_NAME, values, PART_ID_WHERE, id.toStrings()); } @@ -506,37 +502,17 @@ public class AttachmentDatabase extends Database { databaseAttachment.getUrl()); } - - public void updateAttachmentFileName(@NonNull AttachmentId attachmentId, - @Nullable String fileName) - { - SQLiteDatabase database = databaseHelper.getWritableDatabase(); - - ContentValues contentValues = new ContentValues(1); - contentValues.put(FILE_NAME, ExternalStorageUtil.getCleanFileName(fileName)); - - database.update(TABLE_NAME, contentValues, PART_ID_WHERE, attachmentId.toStrings()); - } - public void markAttachmentUploaded(long messageId, Attachment attachment) { ContentValues values = new ContentValues(1); SQLiteDatabase database = databaseHelper.getWritableDatabase(); - values.put(TRANSFER_STATE, TRANSFER_PROGRESS_DONE); + values.put(TRANSFER_STATE, AttachmentTransferProgress.TRANSFER_PROGRESS_DONE); database.update(TABLE_NAME, values, PART_ID_WHERE, ((DatabaseAttachment)attachment).getAttachmentId().toStrings()); notifyConversationListeners(DatabaseFactory.getMmsDatabase(context).getThreadIdForMessage(messageId)); ((DatabaseAttachment) attachment).setUploaded(true); } - public void setTransferState(long messageId, @NonNull Attachment attachment, int transferState) { - if (!(attachment instanceof DatabaseAttachment)) { - throw new AssertionError("Attempt to update attachment that doesn't belong to DB!"); - } - - setTransferState(messageId, ((DatabaseAttachment) attachment).getAttachmentId(), transferState); - } - public void setTransferState(long messageId, @NonNull AttachmentId attachmentId, int transferState) { final ContentValues values = new ContentValues(1); final SQLiteDatabase database = databaseHelper.getWritableDatabase(); @@ -546,14 +522,6 @@ public class AttachmentDatabase extends Database { notifyConversationListeners(DatabaseFactory.getMmsDatabase(context).getThreadIdForMessage(messageId)); } - public boolean hasStickerAttachments() { - String selection = STICKER_PACK_ID + " NOT NULL"; - - try (Cursor cursor = databaseHelper.getReadableDatabase().query(TABLE_NAME, null, selection, null, null, null, null, "1")) { - return cursor != null && cursor.moveToFirst(); - } - } - @SuppressWarnings("WeakerAccess") @VisibleForTesting protected @Nullable InputStream getDataStream(AttachmentId attachmentId, String dataType, long offset) diff --git a/app/src/main/java/org/thoughtcrime/securesms/database/MessagingDatabase.java b/app/src/main/java/org/thoughtcrime/securesms/database/MessagingDatabase.java index 72d4ef6df0..5c92b976f5 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/database/MessagingDatabase.java +++ b/app/src/main/java/org/thoughtcrime/securesms/database/MessagingDatabase.java @@ -7,9 +7,9 @@ import android.text.TextUtils; import net.sqlcipher.database.SQLiteDatabase; -import org.thoughtcrime.securesms.database.documents.Document; -import org.thoughtcrime.securesms.database.documents.IdentityKeyMismatch; -import org.thoughtcrime.securesms.database.documents.IdentityKeyMismatchList; +import org.session.libsession.database.documents.Document; +import org.session.libsession.database.documents.IdentityKeyMismatch; +import org.session.libsession.database.documents.IdentityKeyMismatchList; import org.thoughtcrime.securesms.database.helpers.SQLCipherOpenHelper; import org.session.libsignal.utilities.logging.Log; import org.session.libsignal.libsignal.IdentityKey; @@ -38,27 +38,6 @@ public abstract class MessagingDatabase extends Database implements MmsSmsColumn public abstract void markAsSent(long messageId, boolean secure); public abstract void markUnidentified(long messageId, boolean unidentified); - public void setMismatchedIdentity(long messageId, final Address address, final IdentityKey identityKey) { - List items = new ArrayList() {{ - add(new IdentityKeyMismatch(address, identityKey)); - }}; - - IdentityKeyMismatchList document = new IdentityKeyMismatchList(items); - - SQLiteDatabase database = databaseHelper.getWritableDatabase(); - database.beginTransaction(); - - try { - setDocument(database, messageId, MISMATCHED_IDENTITIES, document); - - database.setTransactionSuccessful(); - } catch (IOException ioe) { - Log.w(TAG, ioe); - } finally { - database.endTransaction(); - } - } - public void addMismatchedIdentity(long messageId, Address address, IdentityKey identityKey) { try { addToDocument(messageId, MISMATCHED_IDENTITIES, diff --git a/app/src/main/java/org/thoughtcrime/securesms/database/MmsDatabase.java b/app/src/main/java/org/thoughtcrime/securesms/database/MmsDatabase.java index 3d2300bfb2..c7cd8a269b 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/database/MmsDatabase.java +++ b/app/src/main/java/org/thoughtcrime/securesms/database/MmsDatabase.java @@ -19,9 +19,7 @@ package org.thoughtcrime.securesms.database; import android.content.ContentValues; import android.content.Context; import android.database.Cursor; -import android.net.Uri; import android.text.TextUtils; -import android.util.Pair; import androidx.annotation.NonNull; import androidx.annotation.Nullable; @@ -38,10 +36,10 @@ import org.json.JSONException; import org.json.JSONObject; import org.thoughtcrime.securesms.ApplicationContext; import org.thoughtcrime.securesms.attachments.MmsNotificationAttachment; -import org.thoughtcrime.securesms.database.documents.IdentityKeyMismatch; -import org.thoughtcrime.securesms.database.documents.IdentityKeyMismatchList; -import org.thoughtcrime.securesms.database.documents.NetworkFailure; -import org.thoughtcrime.securesms.database.documents.NetworkFailureList; +import org.session.libsession.database.documents.IdentityKeyMismatch; +import org.session.libsession.database.documents.IdentityKeyMismatchList; +import org.session.libsession.database.documents.NetworkFailure; +import org.session.libsession.database.documents.NetworkFailureList; import org.thoughtcrime.securesms.database.helpers.SQLCipherOpenHelper; import org.thoughtcrime.securesms.database.model.MediaMmsMessageRecord; import org.thoughtcrime.securesms.database.model.MessageRecord; diff --git a/app/src/main/java/org/thoughtcrime/securesms/database/SmsDatabase.java b/app/src/main/java/org/thoughtcrime/securesms/database/SmsDatabase.java index 20ebbac6b7..300a5c55f8 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/database/SmsDatabase.java +++ b/app/src/main/java/org/thoughtcrime/securesms/database/SmsDatabase.java @@ -23,8 +23,6 @@ import android.database.Cursor; import android.text.TextUtils; import android.util.Pair; -import androidx.annotation.NonNull; - import com.annimon.stream.Stream; import net.sqlcipher.database.SQLiteDatabase; @@ -32,15 +30,15 @@ import net.sqlcipher.database.SQLiteStatement; import org.session.libsignal.utilities.logging.Log; import org.thoughtcrime.securesms.ApplicationContext; -import org.thoughtcrime.securesms.database.documents.IdentityKeyMismatch; -import org.thoughtcrime.securesms.database.documents.IdentityKeyMismatchList; +import org.session.libsession.database.documents.IdentityKeyMismatch; +import org.session.libsession.database.documents.IdentityKeyMismatchList; import org.thoughtcrime.securesms.database.helpers.SQLCipherOpenHelper; import org.thoughtcrime.securesms.database.model.MessageRecord; import org.thoughtcrime.securesms.database.model.SmsMessageRecord; import org.thoughtcrime.securesms.jobs.TrimThreadJob; -import org.thoughtcrime.securesms.sms.IncomingGroupMessage; -import org.thoughtcrime.securesms.sms.IncomingTextMessage; -import org.thoughtcrime.securesms.sms.OutgoingTextMessage; +import org.session.libsession.messaging.messages.signal.IncomingGroupMessage; +import org.session.libsession.messaging.messages.signal.IncomingTextMessage; +import org.session.libsession.messaging.messages.signal.OutgoingTextMessage; import org.session.libsession.messaging.threads.Address; import org.session.libsession.messaging.threads.recipients.Recipient; @@ -51,7 +49,6 @@ import org.session.libsignal.libsignal.util.guava.Optional; import java.io.IOException; import java.security.SecureRandom; -import java.util.HashSet; import java.util.LinkedList; import java.util.List; import java.util.Map; 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 3a5fe5147f..2addeff617 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/database/Storage.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/database/Storage.kt @@ -13,7 +13,6 @@ import org.session.libsession.messaging.messages.visible.VisibleMessage import org.session.libsession.messaging.opengroups.OpenGroup 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.SessionServiceAttachment import org.session.libsession.messaging.sending_receiving.linkpreview.LinkPreview import org.session.libsession.messaging.sending_receiving.quotes.QuoteModel import org.session.libsession.messaging.threads.Address @@ -41,9 +40,9 @@ import org.thoughtcrime.securesms.mms.IncomingMediaMessage import org.thoughtcrime.securesms.mms.OutgoingGroupMediaMessage import org.thoughtcrime.securesms.mms.OutgoingMediaMessage import org.thoughtcrime.securesms.mms.PartAuthority -import org.thoughtcrime.securesms.sms.IncomingGroupMessage -import org.thoughtcrime.securesms.sms.IncomingTextMessage -import org.thoughtcrime.securesms.sms.OutgoingTextMessage +import org.session.libsession.messaging.messages.signal.IncomingGroupMessage +import org.session.libsession.messaging.messages.signal.IncomingTextMessage +import org.session.libsession.messaging.messages.signal.OutgoingTextMessage class Storage(context: Context, helper: SQLCipherOpenHelper) : Database(context, helper), StorageProtocol { override fun getUserPublicKey(): String? { @@ -125,7 +124,7 @@ class Storage(context: Context, helper: SQLCipherOpenHelper) : Database(context, }.mapNotNull { PointerAttachment.forPointer(Optional.of(it)).orNull() } - val mediaMessage = OutgoingMediaMessage.from(message, Recipient.from(context, targetAddress, false), attachments, quote.orNull(), linkPreviews.orNull()) + val mediaMessage = OutgoingMediaMessage.from(message, Recipient.from(context, targetAddress, false), attachments, quote.orNull(), linkPreviews.orNull().firstOrNull()) mmsDatabase.insertSecureDecryptedMessageOutbox(mediaMessage, message.threadID ?: -1, message.sentTimestamp!!) } else { // It seems like we have replaced SignalServiceAttachment with SessionServiceAttachment @@ -331,9 +330,9 @@ class Storage(context: Context, helper: SQLCipherOpenHelper) : Database(context, DatabaseFactory.getLokiMessageDatabase(context).setServerID(messageID, serverID) } - override fun markAsSent(messageID: Long) { + override fun markAsSent(timestamp: Long, author: String) { val database = DatabaseFactory.getMmsSmsDatabase(context) - val messageRecord = database.getMessageFor(messageID)!! + val messageRecord = database.getMessageFor(timestamp, author) ?: return if (messageRecord.isMms) { val mmsDatabase = DatabaseFactory.getMmsDatabase(context) mmsDatabase.markAsSent(messageRecord.getId(), true) @@ -343,9 +342,9 @@ class Storage(context: Context, helper: SQLCipherOpenHelper) : Database(context, } } - override fun markUnidentified(messageID: Long) { + override fun markUnidentified(timestamp: Long, author: String) { val database = DatabaseFactory.getMmsSmsDatabase(context) - val messageRecord = database.getMessageFor(messageID)!! + val messageRecord = database.getMessageFor(timestamp, author) ?: return if (messageRecord.isMms) { val mmsDatabase = DatabaseFactory.getMmsDatabase(context) mmsDatabase.markUnidentified(messageRecord.getId(), true) diff --git a/app/src/main/java/org/thoughtcrime/securesms/database/ThreadDatabase.java b/app/src/main/java/org/thoughtcrime/securesms/database/ThreadDatabase.java index 1bd87e3b6d..98461600bf 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/database/ThreadDatabase.java +++ b/app/src/main/java/org/thoughtcrime/securesms/database/ThreadDatabase.java @@ -29,6 +29,7 @@ import com.annimon.stream.Stream; import net.sqlcipher.database.SQLiteDatabase; +import org.session.libsession.messaging.threads.DistributionTypes; import org.thoughtcrime.securesms.contactshare.ContactUtil; import org.thoughtcrime.securesms.database.MessagingDatabase.MarkedMessageInfo; import org.thoughtcrime.securesms.database.helpers.SQLCipherOpenHelper; @@ -596,14 +597,6 @@ public class ThreadDatabase extends Database { return new Reader(cursor); } - public static class DistributionTypes { - public static final int DEFAULT = 2; - public static final int BROADCAST = 1; - public static final int CONVERSATION = 2; - public static final int ARCHIVE = 3; - public static final int INBOX_ZERO = 4; - } - public class Reader implements Closeable { private final Cursor cursor; diff --git a/app/src/main/java/org/thoughtcrime/securesms/database/helpers/SQLCipherOpenHelper.java b/app/src/main/java/org/thoughtcrime/securesms/database/helpers/SQLCipherOpenHelper.java index 8a629b4e74..a8dad3ce26 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/database/helpers/SQLCipherOpenHelper.java +++ b/app/src/main/java/org/thoughtcrime/securesms/database/helpers/SQLCipherOpenHelper.java @@ -28,6 +28,7 @@ import org.thoughtcrime.securesms.loki.database.LokiBackupFilesDatabase; import org.thoughtcrime.securesms.loki.database.LokiMessageDatabase; import org.thoughtcrime.securesms.loki.database.LokiThreadDatabase; import org.thoughtcrime.securesms.loki.database.LokiUserDatabase; +import org.thoughtcrime.securesms.loki.database.SessionJobDatabase; import org.thoughtcrime.securesms.loki.protocol.ClosedGroupsMigration; public class SQLCipherOpenHelper extends SQLiteOpenHelper { @@ -52,9 +53,10 @@ public class SQLCipherOpenHelper extends SQLiteOpenHelper { private static final int lokiV19 = 40; private static final int lokiV20 = 41; private static final int lokiV21 = 42; + private static final int lokiV22 = 43; // Loki - onUpgrade(...) must be updated to use Loki version numbers if Signal makes any database changes - private static final int DATABASE_VERSION = lokiV21; + private static final int DATABASE_VERSION = lokiV22; private static final String DATABASE_NAME = "signal.db"; private final Context context; @@ -121,6 +123,7 @@ public class SQLCipherOpenHelper extends SQLiteOpenHelper { db.execSQL(LokiUserDatabase.getCreateDisplayNameTableCommand()); db.execSQL(LokiUserDatabase.getCreateServerDisplayNameTableCommand()); db.execSQL(LokiBackupFilesDatabase.getCreateTableCommand()); + db.execSQL(SessionJobDatabase.getCreateSessionJobTableCommand()); executeStatements(db, SmsDatabase.CREATE_INDEXS); executeStatements(db, MmsDatabase.CREATE_INDEXS); @@ -255,6 +258,10 @@ public class SQLCipherOpenHelper extends SQLiteOpenHelper { "ResetThreadSessionJob"); } + if (oldVersion < lokiV22) { + db.execSQL(SessionJobDatabase.getCreateSessionJobTableCommand()); + } + db.setTransactionSuccessful(); } finally { db.endTransaction(); diff --git a/app/src/main/java/org/thoughtcrime/securesms/database/model/MediaMmsMessageRecord.java b/app/src/main/java/org/thoughtcrime/securesms/database/model/MediaMmsMessageRecord.java index dc86623cf1..7088818889 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/database/model/MediaMmsMessageRecord.java +++ b/app/src/main/java/org/thoughtcrime/securesms/database/model/MediaMmsMessageRecord.java @@ -26,8 +26,8 @@ import org.session.libsession.messaging.sending_receiving.sharecontacts.Contact; import org.session.libsession.messaging.sending_receiving.linkpreview.LinkPreview; import org.thoughtcrime.securesms.database.MmsDatabase; import org.thoughtcrime.securesms.database.SmsDatabase.Status; -import org.thoughtcrime.securesms.database.documents.IdentityKeyMismatch; -import org.thoughtcrime.securesms.database.documents.NetworkFailure; +import org.session.libsession.database.documents.IdentityKeyMismatch; +import org.session.libsession.database.documents.NetworkFailure; import org.thoughtcrime.securesms.mms.SlideDeck; import org.session.libsession.messaging.threads.recipients.Recipient; diff --git a/app/src/main/java/org/thoughtcrime/securesms/database/model/MessageRecord.java b/app/src/main/java/org/thoughtcrime/securesms/database/model/MessageRecord.java index a0a8bb3fe6..b41e4ae78e 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/database/model/MessageRecord.java +++ b/app/src/main/java/org/thoughtcrime/securesms/database/model/MessageRecord.java @@ -26,8 +26,8 @@ import android.text.style.StyleSpan; import network.loki.messenger.R; import org.thoughtcrime.securesms.database.MmsSmsColumns; import org.thoughtcrime.securesms.database.SmsDatabase; -import org.thoughtcrime.securesms.database.documents.IdentityKeyMismatch; -import org.thoughtcrime.securesms.database.documents.NetworkFailure; +import org.session.libsession.database.documents.IdentityKeyMismatch; +import org.session.libsession.database.documents.NetworkFailure; import org.session.libsession.messaging.threads.recipients.Recipient; import org.session.libsession.utilities.ExpirationUtil; @@ -158,18 +158,10 @@ public abstract class MessageRecord extends DisplayRecord { return SmsDatabase.Types.isIdentityDefault(type); } - public boolean isIdentityMismatchFailure() { - return mismatches != null && !mismatches.isEmpty(); - } - public boolean isBundleKeyExchange() { return SmsDatabase.Types.isBundleKeyExchange(type); } - public boolean isContentBundleKeyExchange() { - return SmsDatabase.Types.isContentBundleKeyExchange(type); - } - public boolean isIdentityUpdate() { return SmsDatabase.Types.isIdentityUpdate(type); } @@ -195,10 +187,6 @@ public abstract class MessageRecord extends DisplayRecord { return individualRecipient; } - public int getRecipientDeviceId() { - return recipientDeviceId; - } - public long getType() { return type; } @@ -211,10 +199,6 @@ public abstract class MessageRecord extends DisplayRecord { return networkFailures; } - public boolean hasNetworkFailures() { - return networkFailures != null && !networkFailures.isEmpty(); - } - protected SpannableString emphasisAdded(String sequence) { SpannableString spannable = new SpannableString(sequence); spannable.setSpan(new RelativeSizeSpan(0.9f), 0, sequence.length(), Spannable.SPAN_EXCLUSIVE_EXCLUSIVE); @@ -234,10 +218,6 @@ public abstract class MessageRecord extends DisplayRecord { return (int)getId(); } - public int getSubscriptionId() { - return subscriptionId; - } - public long getExpiresIn() { return expiresIn; } diff --git a/app/src/main/java/org/thoughtcrime/securesms/database/model/MmsMessageRecord.java b/app/src/main/java/org/thoughtcrime/securesms/database/model/MmsMessageRecord.java index 0ad53ab397..6b88fdfbd0 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/database/model/MmsMessageRecord.java +++ b/app/src/main/java/org/thoughtcrime/securesms/database/model/MmsMessageRecord.java @@ -8,8 +8,8 @@ import org.session.libsession.messaging.sending_receiving.sharecontacts.Contact; import org.session.libsession.messaging.sending_receiving.linkpreview.LinkPreview; import org.session.libsession.messaging.threads.recipients.Recipient; -import org.thoughtcrime.securesms.database.documents.IdentityKeyMismatch; -import org.thoughtcrime.securesms.database.documents.NetworkFailure; +import org.session.libsession.database.documents.IdentityKeyMismatch; +import org.session.libsession.database.documents.NetworkFailure; import org.thoughtcrime.securesms.mms.Slide; import org.thoughtcrime.securesms.mms.SlideDeck; diff --git a/app/src/main/java/org/thoughtcrime/securesms/database/model/NotificationMmsMessageRecord.java b/app/src/main/java/org/thoughtcrime/securesms/database/model/NotificationMmsMessageRecord.java index 370d2adb84..523aa0ad80 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/database/model/NotificationMmsMessageRecord.java +++ b/app/src/main/java/org/thoughtcrime/securesms/database/model/NotificationMmsMessageRecord.java @@ -23,8 +23,8 @@ import android.text.SpannableString; import network.loki.messenger.R; import org.thoughtcrime.securesms.database.MmsDatabase; import org.thoughtcrime.securesms.database.SmsDatabase.Status; -import org.thoughtcrime.securesms.database.documents.IdentityKeyMismatch; -import org.thoughtcrime.securesms.database.documents.NetworkFailure; +import org.session.libsession.database.documents.IdentityKeyMismatch; +import org.session.libsession.database.documents.NetworkFailure; import org.thoughtcrime.securesms.mms.SlideDeck; import org.session.libsession.messaging.threads.recipients.Recipient; diff --git a/app/src/main/java/org/thoughtcrime/securesms/database/model/Quote.java b/app/src/main/java/org/thoughtcrime/securesms/database/model/Quote.java index fe01e2da41..eb2ec381e0 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/database/model/Quote.java +++ b/app/src/main/java/org/thoughtcrime/securesms/database/model/Quote.java @@ -4,6 +4,7 @@ package org.thoughtcrime.securesms.database.model; import androidx.annotation.NonNull; import androidx.annotation.Nullable; +import org.session.libsession.messaging.sending_receiving.quotes.QuoteModel; import org.session.libsession.messaging.threads.Address; import org.thoughtcrime.securesms.mms.SlideDeck; @@ -42,4 +43,8 @@ public class Quote { public @NonNull SlideDeck getAttachment() { return attachment; } + + public QuoteModel getQuoteModel() { + return new QuoteModel(id, author, text, missing, attachment.asAttachments()); + } } diff --git a/app/src/main/java/org/thoughtcrime/securesms/database/model/SmsMessageRecord.java b/app/src/main/java/org/thoughtcrime/securesms/database/model/SmsMessageRecord.java index bd03f0eb0e..9faabc77c5 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/database/model/SmsMessageRecord.java +++ b/app/src/main/java/org/thoughtcrime/securesms/database/model/SmsMessageRecord.java @@ -24,7 +24,7 @@ import androidx.annotation.NonNull; import org.thoughtcrime.securesms.database.MmsSmsColumns; import org.thoughtcrime.securesms.database.SmsDatabase; -import org.thoughtcrime.securesms.database.documents.IdentityKeyMismatch; +import org.session.libsession.database.documents.IdentityKeyMismatch; import org.session.libsession.messaging.threads.recipients.Recipient; import java.util.LinkedList; diff --git a/app/src/main/java/org/thoughtcrime/securesms/groups/GroupManager.java b/app/src/main/java/org/thoughtcrime/securesms/groups/GroupManager.java index f33ffa29e9..69988b6568 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/groups/GroupManager.java +++ b/app/src/main/java/org/thoughtcrime/securesms/groups/GroupManager.java @@ -2,36 +2,23 @@ package org.thoughtcrime.securesms.groups; import android.content.Context; import android.graphics.Bitmap; -import android.net.Uri; import androidx.annotation.NonNull; import androidx.annotation.Nullable; -import com.google.protobuf.ByteString; - -import org.session.libsession.messaging.sending_receiving.attachments.Attachment; -import org.session.libsession.messaging.sending_receiving.attachments.UriAttachment; import org.session.libsession.messaging.threads.Address; +import org.session.libsession.messaging.threads.DistributionTypes; import org.session.libsession.messaging.threads.recipients.Recipient; import org.session.libsession.utilities.GroupUtil; -import org.session.libsession.utilities.MediaTypes; import org.session.libsession.utilities.TextSecurePreferences; -import org.thoughtcrime.securesms.database.AttachmentDatabase; import org.thoughtcrime.securesms.database.DatabaseFactory; import org.thoughtcrime.securesms.database.GroupDatabase; import org.thoughtcrime.securesms.database.ThreadDatabase; -import org.thoughtcrime.securesms.mms.OutgoingGroupMediaMessage; -import org.thoughtcrime.securesms.providers.BlobProvider; -import org.thoughtcrime.securesms.sms.MessageSender; import org.thoughtcrime.securesms.util.BitmapUtil; -import org.session.libsignal.service.internal.push.SignalServiceProtos.GroupContext; -import java.util.Collection; -import java.util.Collections; import java.util.HashSet; import java.util.LinkedList; -import java.util.List; import java.util.Objects; import java.util.Set; @@ -72,7 +59,7 @@ public class GroupManager { groupDatabase.updateProfilePicture(groupId, avatarBytes); long threadID = DatabaseFactory.getThreadDatabase(context).getOrCreateThreadIdFor( - groupRecipient, ThreadDatabase.DistributionTypes.CONVERSATION); + groupRecipient, DistributionTypes.CONVERSATION); return new GroupActionResult(groupRecipient, threadID); } @@ -95,82 +82,6 @@ public class GroupManager { return groupDatabase.delete(groupId); } - public static GroupActionResult updateGroup(@NonNull Context context, - @NonNull String groupId, - @NonNull Set members, - @Nullable Bitmap avatar, - @Nullable String name, - @NonNull Set admins) - { - final GroupDatabase groupDatabase = DatabaseFactory.getGroupDatabase(context); - final Set
memberAddresses = getMemberAddresses(members); - final Set
adminAddresses = getMemberAddresses(admins); - final byte[] avatarBytes = BitmapUtil.toByteArray(avatar); - - memberAddresses.add(Address.fromSerialized(TextSecurePreferences.getLocalNumber(context))); - groupDatabase.updateMembers(groupId, new LinkedList<>(memberAddresses)); - groupDatabase.updateAdmins(groupId, new LinkedList<>(adminAddresses)); - groupDatabase.updateTitle(groupId, name); - groupDatabase.updateProfilePicture(groupId, avatarBytes); - - if (!GroupUtil.isMmsGroup(groupId)) { - return sendGroupUpdate(context, groupId, memberAddresses, name, avatarBytes, adminAddresses); - } else { - Recipient groupRecipient = Recipient.from(context, Address.fromSerialized(groupId), true); - long threadId = DatabaseFactory.getThreadDatabase(context).getOrCreateThreadIdFor(groupRecipient); - return new GroupActionResult(groupRecipient, threadId); - } - } - - private static GroupActionResult sendGroupUpdate(@NonNull Context context, - @NonNull String groupId, - @NonNull Set
members, - @Nullable String groupName, - @Nullable byte[] avatar, - @NonNull Set
admins) - { - Attachment avatarAttachment = null; - Address groupAddress = Address.fromSerialized(groupId); - Recipient groupRecipient = Recipient.from(context, groupAddress, false); - - List numbers = new LinkedList<>(); - for (Address member : members) { - numbers.add(member.serialize()); - } - - List adminNumbers = new LinkedList<>(); - for (Address admin : admins) { - adminNumbers.add(admin.serialize()); - } - - GroupContext.Builder groupContextBuilder = GroupContext.newBuilder() - .setId(ByteString.copyFrom(GroupUtil.getDecodedGroupIDAsData(groupId))) - .setType(GroupContext.Type.UPDATE) - .addAllMembers(numbers) - .addAllAdmins(adminNumbers); - if (groupName != null) groupContextBuilder.setName(groupName); - GroupContext groupContext = groupContextBuilder.build(); - - if (avatar != null) { - Uri avatarUri = BlobProvider.getInstance().forData(avatar).createForSingleUseInMemory(); - avatarAttachment = new UriAttachment(avatarUri, MediaTypes.IMAGE_PNG, AttachmentDatabase.TRANSFER_PROGRESS_DONE, avatar.length, null, false, false, null); - } - - OutgoingGroupMediaMessage outgoingMessage = new OutgoingGroupMediaMessage(groupRecipient, groupContext, avatarAttachment, 0, null, Collections.emptyList(), Collections.emptyList()); - long threadId = MessageSender.send(context, outgoingMessage, -1, false, null); - - return new GroupActionResult(groupRecipient, threadId); - } - - private static Set
getMemberAddresses(Collection recipients) { - final Set
results = new HashSet<>(); - for (Recipient recipient : recipients) { - results.add(recipient.getAddress()); - } - - return results; - } - public static class GroupActionResult { private Recipient groupRecipient; private long threadId; diff --git a/app/src/main/java/org/thoughtcrime/securesms/jobs/AttachmentDownloadJob.java b/app/src/main/java/org/thoughtcrime/securesms/jobs/AttachmentDownloadJob.java index 794926a15a..82b452d85f 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/jobs/AttachmentDownloadJob.java +++ b/app/src/main/java/org/thoughtcrime/securesms/jobs/AttachmentDownloadJob.java @@ -7,6 +7,7 @@ import androidx.annotation.VisibleForTesting; import org.greenrobot.eventbus.EventBus; import org.session.libsession.messaging.jobs.Data; +import org.session.libsession.messaging.sending_receiving.attachments.AttachmentTransferProgress; import org.session.libsignal.libsignal.InvalidMessageException; import org.session.libsignal.libsignal.util.guava.Optional; import org.session.libsignal.service.api.crypto.AttachmentCipherInputStream; @@ -96,11 +97,11 @@ public class AttachmentDownloadJob extends BaseJob implements InjectableType { final AttachmentDatabase database = DatabaseFactory.getAttachmentDatabase(context); final AttachmentId attachmentId = new AttachmentId(partRowId, partUniqueId); final DatabaseAttachment attachment = database.getAttachment(attachmentId); - final boolean pending = attachment != null && attachment.getTransferState() != AttachmentDatabase.TRANSFER_PROGRESS_DONE; + final boolean pending = attachment != null && attachment.getTransferState() != AttachmentTransferProgress.TRANSFER_PROGRESS_DONE; if (pending && (manual || AttachmentUtil.isAutoDownloadPermitted(context, attachment))) { Log.i(TAG, "onAdded() Marking attachment progress as 'started'"); - database.setTransferState(messageId, attachmentId, AttachmentDatabase.TRANSFER_PROGRESS_STARTED); + database.setTransferState(messageId, attachmentId, AttachmentTransferProgress.TRANSFER_PROGRESS_STARTED); } } @@ -129,12 +130,12 @@ public class AttachmentDownloadJob extends BaseJob implements InjectableType { if (!manual && !AttachmentUtil.isAutoDownloadPermitted(context, attachment)) { Log.w(TAG, "Attachment can't be auto downloaded..."); - database.setTransferState(messageId, attachmentId, AttachmentDatabase.TRANSFER_PROGRESS_PENDING); + database.setTransferState(messageId, attachmentId, AttachmentTransferProgress.TRANSFER_PROGRESS_PENDING); return; } Log.i(TAG, "Downloading push part " + attachmentId); - database.setTransferState(messageId, attachmentId, AttachmentDatabase.TRANSFER_PROGRESS_STARTED); + database.setTransferState(messageId, attachmentId, AttachmentTransferProgress.TRANSFER_PROGRESS_STARTED); retrieveAttachment(messageId, attachmentId, attachment); } diff --git a/app/src/main/java/org/thoughtcrime/securesms/jobs/PushDecryptJob.java b/app/src/main/java/org/thoughtcrime/securesms/jobs/PushDecryptJob.java index 2e966993a3..3d1ee9d0ea 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/jobs/PushDecryptJob.java +++ b/app/src/main/java/org/thoughtcrime/securesms/jobs/PushDecryptJob.java @@ -15,6 +15,7 @@ import com.annimon.stream.Collectors; import com.annimon.stream.Stream; import org.session.libsession.messaging.jobs.Data; +import org.session.libsession.messaging.threads.DistributionTypes; import org.session.libsignal.metadata.InvalidMetadataMessageException; import org.session.libsignal.metadata.ProtocolInvalidMessageException; import org.session.libsignal.service.api.crypto.SignalServiceCipher; @@ -34,7 +35,6 @@ import org.session.libsession.utilities.TextSecurePreferences; import org.thoughtcrime.securesms.contactshare.ContactModelMapper; import org.thoughtcrime.securesms.crypto.IdentityKeyUtil; -import org.thoughtcrime.securesms.database.AttachmentDatabase; import org.thoughtcrime.securesms.database.DatabaseFactory; import org.thoughtcrime.securesms.database.GroupDatabase; import org.thoughtcrime.securesms.database.MessagingDatabase.InsertResult; @@ -63,9 +63,9 @@ import org.thoughtcrime.securesms.mms.IncomingMediaMessage; import org.thoughtcrime.securesms.mms.MmsException; import org.thoughtcrime.securesms.mms.OutgoingMediaMessage; import org.thoughtcrime.securesms.notifications.NotificationChannels; -import org.thoughtcrime.securesms.sms.IncomingEncryptedMessage; -import org.thoughtcrime.securesms.sms.IncomingTextMessage; -import org.thoughtcrime.securesms.sms.OutgoingTextMessage; +import org.session.libsession.messaging.messages.signal.IncomingEncryptedMessage; +import org.session.libsession.messaging.messages.signal.IncomingTextMessage; +import org.session.libsession.messaging.messages.signal.OutgoingTextMessage; import org.session.libsignal.libsignal.util.guava.Optional; import org.session.libsignal.service.api.SignalServiceMessageSender; import org.session.libsignal.service.api.messages.SignalServiceContent; @@ -346,7 +346,7 @@ public class PushDecryptJob extends BaseJob implements InjectableType { attachments, message.getTimestamp(), -1, message.getExpiresInSeconds() * 1000, - ThreadDatabase.DistributionTypes.DEFAULT, quote.orNull(), + DistributionTypes.DEFAULT, quote.orNull(), sharedContacts.or(Collections.emptyList()), linkPreviews.or(Collections.emptyList()), Collections.emptyList(), Collections.emptyList()); diff --git a/app/src/main/java/org/thoughtcrime/securesms/jobs/PushGroupSendJob.java b/app/src/main/java/org/thoughtcrime/securesms/jobs/PushGroupSendJob.java index 848ff045eb..ee266d43a9 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/jobs/PushGroupSendJob.java +++ b/app/src/main/java/org/thoughtcrime/securesms/jobs/PushGroupSendJob.java @@ -21,8 +21,8 @@ import org.thoughtcrime.securesms.crypto.UnidentifiedAccessUtil; import org.thoughtcrime.securesms.database.DatabaseFactory; import org.thoughtcrime.securesms.database.MmsDatabase; import org.thoughtcrime.securesms.database.NoSuchMessageException; -import org.thoughtcrime.securesms.database.documents.IdentityKeyMismatch; -import org.thoughtcrime.securesms.database.documents.NetworkFailure; +import org.session.libsession.database.documents.IdentityKeyMismatch; +import org.session.libsession.database.documents.NetworkFailure; import org.thoughtcrime.securesms.dependencies.InjectableType; import org.thoughtcrime.securesms.jobmanager.Job; import org.thoughtcrime.securesms.jobmanager.JobManager; diff --git a/app/src/main/java/org/thoughtcrime/securesms/linkpreview/LinkPreviewRepository.java b/app/src/main/java/org/thoughtcrime/securesms/linkpreview/LinkPreviewRepository.java index 583a7d5465..467a7bed20 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/linkpreview/LinkPreviewRepository.java +++ b/app/src/main/java/org/thoughtcrime/securesms/linkpreview/LinkPreviewRepository.java @@ -9,6 +9,7 @@ import androidx.annotation.Nullable; import com.google.android.gms.common.util.IOUtils; +import org.session.libsession.messaging.sending_receiving.attachments.AttachmentTransferProgress; import org.session.libsession.utilities.MediaTypes; import org.thoughtcrime.securesms.ApplicationContext; import org.thoughtcrime.securesms.database.AttachmentDatabase; @@ -192,7 +193,7 @@ public class LinkPreviewRepository implements InjectableType { return Optional.of(new UriAttachment(uri, uri, contentType, - AttachmentDatabase.TRANSFER_PROGRESS_STARTED, + AttachmentTransferProgress.TRANSFER_PROGRESS_STARTED, bytes.length, bitmap.getWidth(), bitmap.getHeight(), diff --git a/app/src/main/java/org/thoughtcrime/securesms/linkpreview/LinkPreviewViewModel.java b/app/src/main/java/org/thoughtcrime/securesms/linkpreview/LinkPreviewViewModel.java index f18a54fa13..60c6431906 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/linkpreview/LinkPreviewViewModel.java +++ b/app/src/main/java/org/thoughtcrime/securesms/linkpreview/LinkPreviewViewModel.java @@ -43,13 +43,13 @@ public class LinkPreviewViewModel extends ViewModel { return linkPreviewState.getValue() != null && linkPreviewState.getValue().getLinkPreview().isPresent(); } - public @NonNull List getActiveLinkPreviews() { + public Optional getActiveLinkPreview() { final LinkPreviewState state = linkPreviewState.getValue(); if (state == null || !state.getLinkPreview().isPresent()) { - return Collections.emptyList(); + return Optional.absent(); } else { - return Collections.singletonList(state.getLinkPreview().get()); + return state.getLinkPreview(); } } diff --git a/app/src/main/java/org/thoughtcrime/securesms/loki/activities/CreateClosedGroupActivity.kt b/app/src/main/java/org/thoughtcrime/securesms/loki/activities/CreateClosedGroupActivity.kt index af0f5cc57b..7eee06e54e 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/loki/activities/CreateClosedGroupActivity.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/loki/activities/CreateClosedGroupActivity.kt @@ -16,15 +16,14 @@ import nl.komponents.kovenant.ui.successUi import org.thoughtcrime.securesms.PassphraseRequiredActionBarActivity import org.thoughtcrime.securesms.conversation.ConversationActivity import org.session.libsession.messaging.threads.Address +import org.session.libsession.messaging.threads.DistributionTypes import org.thoughtcrime.securesms.database.DatabaseFactory -import org.thoughtcrime.securesms.database.ThreadDatabase import org.thoughtcrime.securesms.loki.utilities.fadeIn import org.thoughtcrime.securesms.loki.utilities.fadeOut import org.thoughtcrime.securesms.mms.GlideApp import org.session.libsession.messaging.threads.recipients.Recipient import org.session.libsession.utilities.TextSecurePreferences import org.thoughtcrime.securesms.loki.protocol.ClosedGroupsProtocolV2 -import org.thoughtcrime.securesms.loki.protocol.MultiDeviceProtocol //TODO Refactor to avoid using kotlinx.android.synthetic class CreateClosedGroupActivity : PassphraseRequiredActionBarActivity(), LoaderManager.LoaderCallbacks> { @@ -128,7 +127,7 @@ class CreateClosedGroupActivity : PassphraseRequiredActionBarActivity(), LoaderM private fun openConversationActivity(context: Context, threadId: Long, recipient: Recipient) { val intent = Intent(context, ConversationActivity::class.java) intent.putExtra(ConversationActivity.THREAD_ID_EXTRA, threadId) - intent.putExtra(ConversationActivity.DISTRIBUTION_TYPE_EXTRA, ThreadDatabase.DistributionTypes.DEFAULT) + intent.putExtra(ConversationActivity.DISTRIBUTION_TYPE_EXTRA, DistributionTypes.DEFAULT) intent.putExtra(ConversationActivity.ADDRESS_EXTRA, recipient.address) context.startActivity(intent) } diff --git a/app/src/main/java/org/thoughtcrime/securesms/loki/activities/CreatePrivateChatActivity.kt b/app/src/main/java/org/thoughtcrime/securesms/loki/activities/CreatePrivateChatActivity.kt index 0fd6793423..b2eab44fb9 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/loki/activities/CreatePrivateChatActivity.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/loki/activities/CreatePrivateChatActivity.kt @@ -18,6 +18,7 @@ import network.loki.messenger.R import org.thoughtcrime.securesms.PassphraseRequiredActionBarActivity import org.thoughtcrime.securesms.conversation.ConversationActivity import org.session.libsession.messaging.threads.Address +import org.session.libsession.messaging.threads.DistributionTypes import org.thoughtcrime.securesms.database.DatabaseFactory import org.thoughtcrime.securesms.database.ThreadDatabase import org.thoughtcrime.securesms.loki.fragments.ScanQRCodeWrapperFragment @@ -69,7 +70,7 @@ class CreatePrivateChatActivity : PassphraseRequiredActionBarActivity(), ScanQRC intent.setDataAndType(getIntent().data, getIntent().type) val existingThread = DatabaseFactory.getThreadDatabase(this).getThreadIdIfExistsFor(recipient) intent.putExtra(ConversationActivity.THREAD_ID_EXTRA, existingThread) - intent.putExtra(ConversationActivity.DISTRIBUTION_TYPE_EXTRA, ThreadDatabase.DistributionTypes.DEFAULT) + intent.putExtra(ConversationActivity.DISTRIBUTION_TYPE_EXTRA, DistributionTypes.DEFAULT) startActivity(intent) finish() } diff --git a/app/src/main/java/org/thoughtcrime/securesms/loki/activities/EditClosedGroupActivity.kt b/app/src/main/java/org/thoughtcrime/securesms/loki/activities/EditClosedGroupActivity.kt index 65bf5ef905..e5605e2894 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/loki/activities/EditClosedGroupActivity.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/loki/activities/EditClosedGroupActivity.kt @@ -301,8 +301,6 @@ class EditClosedGroupActivity : PassphraseRequiredActionBarActivity() { loaderContainer.fadeOut() isLoading = false } - } else { - GroupManager.updateGroup(this, groupID, members, null, name, admins) } } } \ No newline at end of file diff --git a/app/src/main/java/org/thoughtcrime/securesms/loki/activities/QRCodeActivity.kt b/app/src/main/java/org/thoughtcrime/securesms/loki/activities/QRCodeActivity.kt index db98bd0989..f6b7e64433 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/loki/activities/QRCodeActivity.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/loki/activities/QRCodeActivity.kt @@ -17,6 +17,7 @@ import network.loki.messenger.R import org.thoughtcrime.securesms.PassphraseRequiredActionBarActivity import org.thoughtcrime.securesms.conversation.ConversationActivity import org.session.libsession.messaging.threads.Address +import org.session.libsession.messaging.threads.DistributionTypes import org.thoughtcrime.securesms.database.DatabaseFactory import org.thoughtcrime.securesms.database.ThreadDatabase import org.thoughtcrime.securesms.loki.fragments.ScanQRCodeWrapperFragment @@ -60,7 +61,7 @@ class QRCodeActivity : PassphraseRequiredActionBarActivity(), ScanQRCodeWrapperF intent.setDataAndType(getIntent().data, getIntent().type) val existingThread = DatabaseFactory.getThreadDatabase(this).getThreadIdIfExistsFor(recipient) intent.putExtra(ConversationActivity.THREAD_ID_EXTRA, existingThread) - intent.putExtra(ConversationActivity.DISTRIBUTION_TYPE_EXTRA, ThreadDatabase.DistributionTypes.DEFAULT) + intent.putExtra(ConversationActivity.DISTRIBUTION_TYPE_EXTRA, DistributionTypes.DEFAULT) startActivity(intent) finish() } diff --git a/app/src/main/java/org/thoughtcrime/securesms/loki/database/SessionJobDatabase.kt b/app/src/main/java/org/thoughtcrime/securesms/loki/database/SessionJobDatabase.kt index 30960a9c96..38975e2ffd 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/loki/database/SessionJobDatabase.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/loki/database/SessionJobDatabase.kt @@ -12,7 +12,7 @@ import org.thoughtcrime.securesms.loki.utilities.* class SessionJobDatabase(context: Context, helper: SQLCipherOpenHelper) : Database(context, helper) { companion object { - private val sessionJobTable = "loki_thread_session_reset_database" + private val sessionJobTable = "session_job_database" val jobID = "job_id" val jobType = "job_type" val failureCount = "failure_count" diff --git a/app/src/main/java/org/thoughtcrime/securesms/loki/protocol/ClosedGroupsProtocolV2.kt b/app/src/main/java/org/thoughtcrime/securesms/loki/protocol/ClosedGroupsProtocolV2.kt index 9fba4b66ef..d9e26ba4f0 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/loki/protocol/ClosedGroupsProtocolV2.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/loki/protocol/ClosedGroupsProtocolV2.kt @@ -26,8 +26,8 @@ import org.thoughtcrime.securesms.loki.api.LokiPushNotificationManager.ClosedGro import org.thoughtcrime.securesms.loki.api.SessionProtocolImpl import org.thoughtcrime.securesms.loki.database.LokiAPIDatabase import org.thoughtcrime.securesms.mms.OutgoingGroupMediaMessage -import org.thoughtcrime.securesms.sms.IncomingGroupMessage -import org.thoughtcrime.securesms.sms.IncomingTextMessage +import org.session.libsession.messaging.messages.signal.IncomingGroupMessage +import org.session.libsession.messaging.messages.signal.IncomingTextMessage import org.session.libsignal.utilities.Hex import org.session.libsession.messaging.threads.Address diff --git a/app/src/main/java/org/thoughtcrime/securesms/loki/views/MessageAudioView.kt b/app/src/main/java/org/thoughtcrime/securesms/loki/views/MessageAudioView.kt index 350dddaa3d..9c79d2dc3c 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/loki/views/MessageAudioView.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/loki/views/MessageAudioView.kt @@ -20,6 +20,7 @@ import network.loki.messenger.R import org.greenrobot.eventbus.EventBus import org.greenrobot.eventbus.Subscribe import org.greenrobot.eventbus.ThreadMode +import org.session.libsession.messaging.sending_receiving.attachments.AttachmentTransferProgress import org.thoughtcrime.securesms.ApplicationContext import org.session.libsession.messaging.sending_receiving.attachments.DatabaseAttachment import org.thoughtcrime.securesms.audio.AudioSlidePlayer @@ -152,7 +153,7 @@ class MessageAudioView: FrameLayout, AudioSlidePlayer.Listener { downloadProgress.progress = 0 } } - (showControls && audio.transferState == AttachmentDatabase.TRANSFER_PROGRESS_STARTED) -> { + (showControls && audio.transferState == AttachmentTransferProgress.TRANSFER_PROGRESS_STARTED) -> { controlToggle.displayQuick(downloadProgress) seekBar.isEnabled = false downloadProgress.isIndeterminate = true diff --git a/app/src/main/java/org/thoughtcrime/securesms/mms/AudioSlide.java b/app/src/main/java/org/thoughtcrime/securesms/mms/AudioSlide.java index 877a68f76d..9a1885ab90 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/mms/AudioSlide.java +++ b/app/src/main/java/org/thoughtcrime/securesms/mms/AudioSlide.java @@ -25,6 +25,7 @@ import androidx.annotation.Nullable; import network.loki.messenger.R; import org.session.libsession.messaging.sending_receiving.attachments.Attachment; +import org.session.libsession.messaging.sending_receiving.attachments.AttachmentTransferProgress; import org.session.libsession.messaging.sending_receiving.attachments.UriAttachment; import org.session.libsession.utilities.MediaTypes; import org.thoughtcrime.securesms.database.AttachmentDatabase; @@ -38,7 +39,7 @@ public class AudioSlide extends Slide { } public AudioSlide(Context context, Uri uri, long dataSize, String contentType, boolean voiceNote) { - super(context, new UriAttachment(uri, null, contentType, AttachmentDatabase.TRANSFER_PROGRESS_STARTED, dataSize, 0, 0, null, null, voiceNote, false, null)); + super(context, new UriAttachment(uri, null, contentType, AttachmentTransferProgress.TRANSFER_PROGRESS_STARTED, dataSize, 0, 0, null, null, voiceNote, false, null)); } public AudioSlide(Context context, Attachment attachment) { diff --git a/app/src/main/java/org/thoughtcrime/securesms/mms/OutgoingExpirationUpdateMessage.java b/app/src/main/java/org/thoughtcrime/securesms/mms/OutgoingExpirationUpdateMessage.java index 91fcab901d..85860ca071 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/mms/OutgoingExpirationUpdateMessage.java +++ b/app/src/main/java/org/thoughtcrime/securesms/mms/OutgoingExpirationUpdateMessage.java @@ -1,7 +1,7 @@ package org.thoughtcrime.securesms.mms; import org.session.libsession.messaging.sending_receiving.attachments.Attachment; -import org.thoughtcrime.securesms.database.ThreadDatabase; +import org.session.libsession.messaging.threads.DistributionTypes; import org.session.libsession.messaging.threads.recipients.Recipient; import java.util.Collections; @@ -11,7 +11,7 @@ public class OutgoingExpirationUpdateMessage extends OutgoingSecureMediaMessage public OutgoingExpirationUpdateMessage(Recipient recipient, long sentTimeMillis, long expiresIn) { super(recipient, "", new LinkedList(), sentTimeMillis, - ThreadDatabase.DistributionTypes.CONVERSATION, expiresIn, null, Collections.emptyList(), + DistributionTypes.CONVERSATION, expiresIn, null, Collections.emptyList(), Collections.emptyList()); } diff --git a/app/src/main/java/org/thoughtcrime/securesms/mms/OutgoingGroupMediaMessage.java b/app/src/main/java/org/thoughtcrime/securesms/mms/OutgoingGroupMediaMessage.java index cf63d5a058..e5c66d4923 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/mms/OutgoingGroupMediaMessage.java +++ b/app/src/main/java/org/thoughtcrime/securesms/mms/OutgoingGroupMediaMessage.java @@ -3,7 +3,7 @@ package org.thoughtcrime.securesms.mms; import androidx.annotation.NonNull; import androidx.annotation.Nullable; -import org.thoughtcrime.securesms.database.ThreadDatabase; +import org.session.libsession.messaging.threads.DistributionTypes; import org.session.libsession.messaging.sending_receiving.attachments.Attachment; import org.session.libsession.messaging.sending_receiving.sharecontacts.Contact; import org.session.libsession.messaging.sending_receiving.linkpreview.LinkPreview; @@ -32,7 +32,7 @@ public class OutgoingGroupMediaMessage extends OutgoingSecureMediaMessage { throws IOException { super(recipient, encodedGroupContext, avatar, sentTimeMillis, - ThreadDatabase.DistributionTypes.CONVERSATION, expiresIn, quote, contacts, previews); + DistributionTypes.CONVERSATION, expiresIn, quote, contacts, previews); this.group = GroupContext.parseFrom(Base64.decode(encodedGroupContext)); } @@ -48,7 +48,7 @@ public class OutgoingGroupMediaMessage extends OutgoingSecureMediaMessage { super(recipient, Base64.encodeBytes(group.toByteArray()), new LinkedList() {{if (avatar != null) add(avatar);}}, System.currentTimeMillis(), - ThreadDatabase.DistributionTypes.CONVERSATION, expireIn, quote, contacts, previews); + DistributionTypes.CONVERSATION, expireIn, quote, contacts, previews); this.group = group; } @@ -65,7 +65,7 @@ public class OutgoingGroupMediaMessage extends OutgoingSecureMediaMessage { super(recipient, Base64.encodeBytes(group.toByteArray()), new LinkedList() {{if (avatar != null) add(avatar);}}, sentTime, - ThreadDatabase.DistributionTypes.CONVERSATION, expireIn, quote, contacts, previews); + DistributionTypes.CONVERSATION, expireIn, quote, contacts, previews); this.group = group; } diff --git a/app/src/main/java/org/thoughtcrime/securesms/mms/OutgoingMediaMessage.java b/app/src/main/java/org/thoughtcrime/securesms/mms/OutgoingMediaMessage.java index fb22876181..d90496026a 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/mms/OutgoingMediaMessage.java +++ b/app/src/main/java/org/thoughtcrime/securesms/mms/OutgoingMediaMessage.java @@ -5,9 +5,9 @@ import androidx.annotation.Nullable; import android.text.TextUtils; import org.session.libsession.messaging.messages.visible.VisibleMessage; -import org.thoughtcrime.securesms.database.ThreadDatabase; -import org.thoughtcrime.securesms.database.documents.IdentityKeyMismatch; -import org.thoughtcrime.securesms.database.documents.NetworkFailure; +import org.session.libsession.messaging.threads.DistributionTypes; +import org.session.libsession.database.documents.IdentityKeyMismatch; +import org.session.libsession.database.documents.NetworkFailure; import org.session.libsession.messaging.sending_receiving.attachments.Attachment; import org.session.libsession.messaging.sending_receiving.sharecontacts.Contact; import org.session.libsession.messaging.sending_receiving.linkpreview.LinkPreview; @@ -17,6 +17,7 @@ import org.session.libsession.messaging.threads.recipients.Recipient; import java.util.Collections; import java.util.LinkedList; import java.util.List; +import java.util.Optional; public class OutgoingMediaMessage { @@ -66,7 +67,7 @@ public class OutgoingMediaMessage { @NonNull List linkPreviews) { this(recipient, - buildMessage(slideDeck, message), + buildMessage(message), slideDeck.asAttachments(), sentTimeMillis, subscriptionId, expiresIn, distributionType, outgoingQuote, @@ -93,11 +94,15 @@ public class OutgoingMediaMessage { Recipient recipient, List attachments, @Nullable QuoteModel outgoingQuote, - @NonNull List linkPreviews) + @Nullable LinkPreview linkPreview) { + List previews = Collections.emptyList(); + if (linkPreview != null) { + previews = Collections.singletonList(linkPreview); + } return new OutgoingMediaMessage(recipient, message.getText(), attachments, message.getSentTimestamp(), -1, - recipient.getExpireMessages() * 1000, ThreadDatabase.DistributionTypes.DEFAULT, outgoingQuote, Collections.emptyList(), - linkPreviews, Collections.emptyList(), Collections.emptyList()); + recipient.getExpireMessages() * 1000, DistributionTypes.DEFAULT, outgoingQuote, Collections.emptyList(), + previews, Collections.emptyList(), Collections.emptyList()); } public Recipient getRecipient() { @@ -160,7 +165,7 @@ public class OutgoingMediaMessage { return identityKeyMismatches; } - private static String buildMessage(SlideDeck slideDeck, String message) { + private static String buildMessage(String message) { if (!TextUtils.isEmpty(message)) { return message; } diff --git a/app/src/main/java/org/thoughtcrime/securesms/mms/Slide.java b/app/src/main/java/org/thoughtcrime/securesms/mms/Slide.java index 0c036b96ca..2eecd9a0de 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/mms/Slide.java +++ b/app/src/main/java/org/thoughtcrime/securesms/mms/Slide.java @@ -23,7 +23,7 @@ import androidx.annotation.DrawableRes; import androidx.annotation.NonNull; import androidx.annotation.Nullable; -import org.thoughtcrime.securesms.database.AttachmentDatabase; +import org.session.libsession.messaging.sending_receiving.attachments.AttachmentTransferProgress; import org.thoughtcrime.securesms.util.MediaUtil; import org.session.libsignal.libsignal.util.guava.Optional; @@ -135,8 +135,8 @@ public abstract class Slide { } public boolean isPendingDownload() { - return getTransferState() == AttachmentDatabase.TRANSFER_PROGRESS_FAILED || - getTransferState() == AttachmentDatabase.TRANSFER_PROGRESS_PENDING; + return getTransferState() == AttachmentTransferProgress.TRANSFER_PROGRESS_FAILED || + getTransferState() == AttachmentTransferProgress.TRANSFER_PROGRESS_PENDING; } public int getTransferState() { @@ -172,7 +172,7 @@ public abstract class Slide { return new UriAttachment(uri, hasThumbnail ? uri : null, resolvedType, - AttachmentDatabase.TRANSFER_PROGRESS_STARTED, + AttachmentTransferProgress.TRANSFER_PROGRESS_STARTED, size, width, height, diff --git a/app/src/main/java/org/thoughtcrime/securesms/notifications/AndroidAutoReplyReceiver.java b/app/src/main/java/org/thoughtcrime/securesms/notifications/AndroidAutoReplyReceiver.java index d89acb0273..c4dd4f5203 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/notifications/AndroidAutoReplyReceiver.java +++ b/app/src/main/java/org/thoughtcrime/securesms/notifications/AndroidAutoReplyReceiver.java @@ -25,18 +25,19 @@ import android.os.AsyncTask; import android.os.Bundle; import androidx.core.app.RemoteInput; +import org.session.libsession.messaging.messages.visible.VisibleMessage; +import org.session.libsession.messaging.sending_receiving.MessageSender; import org.thoughtcrime.securesms.ApplicationContext; import org.session.libsession.messaging.threads.Address; import org.thoughtcrime.securesms.database.DatabaseFactory; import org.thoughtcrime.securesms.database.MessagingDatabase.MarkedMessageInfo; +import org.thoughtcrime.securesms.mms.MmsException; import org.thoughtcrime.securesms.mms.OutgoingMediaMessage; import org.session.libsession.messaging.threads.recipients.Recipient; -import org.thoughtcrime.securesms.sms.MessageSender; -import org.thoughtcrime.securesms.sms.OutgoingTextMessage; +import org.session.libsession.messaging.messages.signal.OutgoingTextMessage; import org.session.libsignal.utilities.logging.Log; import java.util.Collections; -import java.util.LinkedList; import java.util.List; /** @@ -72,17 +73,29 @@ public class AndroidAutoReplyReceiver extends BroadcastReceiver { long replyThreadId; - int subscriptionId = recipient.getDefaultSubscriptionId().or(-1); - long expiresIn = recipient.getExpireMessages() * 1000L; + if (threadId == -1) { + replyThreadId = DatabaseFactory.getThreadDatabase(context).getOrCreateThreadIdFor(recipient); + } else { + replyThreadId = threadId; + } + + VisibleMessage message = new VisibleMessage(); + message.setText(responseText.toString()); + message.setSentTimestamp(System.currentTimeMillis()); + MessageSender.send(message, recipient.getAddress()); if (recipient.isGroupRecipient()) { Log.w("AndroidAutoReplyReceiver", "GroupRecipient, Sending media message"); - OutgoingMediaMessage reply = new OutgoingMediaMessage(recipient, responseText.toString(), new LinkedList<>(), System.currentTimeMillis(), subscriptionId, expiresIn, 0, null, Collections.emptyList(), Collections.emptyList(), Collections.emptyList(), Collections.emptyList()); - replyThreadId = MessageSender.send(context, reply, threadId, false, null); + OutgoingMediaMessage reply = OutgoingMediaMessage.from(message, recipient, Collections.emptyList(), null, null); + try { + DatabaseFactory.getMmsDatabase(context).insertMessageOutbox(reply, replyThreadId, false, null); + } catch (MmsException e) { + Log.w(TAG, e); + } } else { Log.w("AndroidAutoReplyReceiver", "Sending regular message "); - OutgoingTextMessage reply = new OutgoingTextMessage(recipient, responseText.toString(), expiresIn, subscriptionId); - replyThreadId = MessageSender.send(context, reply, threadId, false, null); + OutgoingTextMessage reply = OutgoingTextMessage.from(message, recipient); + DatabaseFactory.getSmsDatabase(context).insertMessageOutbox(replyThreadId, reply, false, System.currentTimeMillis(), null); } List messageIds = DatabaseFactory.getThreadDatabase(context).setRead(replyThreadId, true); diff --git a/app/src/main/java/org/thoughtcrime/securesms/notifications/RemoteReplyReceiver.java b/app/src/main/java/org/thoughtcrime/securesms/notifications/RemoteReplyReceiver.java index 2110440610..dd11c8be43 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/notifications/RemoteReplyReceiver.java +++ b/app/src/main/java/org/thoughtcrime/securesms/notifications/RemoteReplyReceiver.java @@ -25,17 +25,18 @@ import android.os.AsyncTask; import android.os.Bundle; import androidx.core.app.RemoteInput; +import org.session.libsession.messaging.messages.signal.OutgoingTextMessage; +import org.session.libsession.messaging.messages.visible.VisibleMessage; +import org.session.libsignal.utilities.logging.Log; import org.thoughtcrime.securesms.ApplicationContext; import org.session.libsession.messaging.threads.Address; import org.thoughtcrime.securesms.database.DatabaseFactory; import org.thoughtcrime.securesms.database.MessagingDatabase.MarkedMessageInfo; +import org.thoughtcrime.securesms.mms.MmsException; import org.thoughtcrime.securesms.mms.OutgoingMediaMessage; import org.session.libsession.messaging.threads.recipients.Recipient; -import org.thoughtcrime.securesms.sms.MessageSender; -import org.thoughtcrime.securesms.sms.OutgoingEncryptedMessage; import java.util.Collections; -import java.util.LinkedList; import java.util.List; /** @@ -68,21 +69,24 @@ public class RemoteReplyReceiver extends BroadcastReceiver { new AsyncTask() { @Override protected Void doInBackground(Void... params) { - long threadId; - Recipient recipient = Recipient.from(context, address, false); - int subscriptionId = recipient.getDefaultSubscriptionId().or(-1); - long expiresIn = recipient.getExpireMessages() * 1000L; + long threadId = DatabaseFactory.getThreadDatabase(context).getOrCreateThreadIdFor(recipient); + VisibleMessage message = new VisibleMessage(); + message.setText(responseText.toString()); switch (replyMethod) { case GroupMessage: { - OutgoingMediaMessage reply = new OutgoingMediaMessage(recipient, responseText.toString(), new LinkedList<>(), System.currentTimeMillis(), subscriptionId, expiresIn, 0, null, Collections.emptyList(), Collections.emptyList(), Collections.emptyList(), Collections.emptyList()); - threadId = MessageSender.send(context, reply, -1, false, null); + OutgoingMediaMessage reply = OutgoingMediaMessage.from(message, recipient, Collections.emptyList(), null, null); + try { + DatabaseFactory.getMmsDatabase(context).insertMessageOutbox(reply, threadId, false, null); + } catch (MmsException e) { + Log.w(TAG, e); + } break; } case SecureMessage: { - OutgoingEncryptedMessage reply = new OutgoingEncryptedMessage(recipient, responseText.toString(), expiresIn); - threadId = MessageSender.send(context, reply, -1, false, null); + OutgoingTextMessage reply = OutgoingTextMessage.from(message, recipient); + DatabaseFactory.getSmsDatabase(context).insertMessageOutbox(threadId, reply, false, System.currentTimeMillis(), null); break; } default: 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 401a6c7e27..e28ffbd9e2 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/service/ExpiringMessageManager.java +++ b/app/src/main/java/org/thoughtcrime/securesms/service/ExpiringMessageManager.java @@ -103,17 +103,18 @@ public class ExpiringMessageManager implements SSKEnvironment.MessageExpirationM } @Override - public void startAnyExpiration(long messageID) { - MessageRecord messageRecord = DatabaseFactory.getMmsSmsDatabase(context).getMessageFor(messageID); + public void startAnyExpiration(long timestamp, @NotNull String author) { + MessageRecord messageRecord = DatabaseFactory.getMmsSmsDatabase(context).getMessageFor(timestamp, author); if (messageRecord != null) { boolean mms = messageRecord.isMms(); Recipient recipient = messageRecord.getRecipient(); + if (recipient.getExpireMessages() <= 0) return; if (mms) { - mmsDatabase.markExpireStarted(messageID); + mmsDatabase.markExpireStarted(messageRecord.getId()); } else { - smsDatabase.markExpireStarted(messageID); + smsDatabase.markExpireStarted(messageRecord.getId()); } - scheduleDeletion(messageID, mms, recipient.getExpireMessages()); + scheduleDeletion(messageRecord.getId(), mms, recipient.getExpireMessages()); } } diff --git a/app/src/main/java/org/thoughtcrime/securesms/service/QuickResponseService.java b/app/src/main/java/org/thoughtcrime/securesms/service/QuickResponseService.java index d657be284b..ada9bb2513 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/service/QuickResponseService.java +++ b/app/src/main/java/org/thoughtcrime/securesms/service/QuickResponseService.java @@ -7,11 +7,13 @@ import android.text.TextUtils; import android.widget.Toast; import network.loki.messenger.R; + +import org.session.libsession.messaging.messages.visible.VisibleMessage; import org.session.libsession.messaging.threads.Address; import org.session.libsignal.utilities.logging.Log; import org.session.libsession.messaging.threads.recipients.Recipient; -import org.thoughtcrime.securesms.sms.MessageSender; -import org.thoughtcrime.securesms.sms.OutgoingTextMessage; +import org.session.libsession.messaging.sending_receiving.MessageSender; +import org.session.libsession.messaging.messages.signal.OutgoingTextMessage; import org.thoughtcrime.securesms.util.Rfc5724Uri; import java.net.URISyntaxException; @@ -47,13 +49,11 @@ public class QuickResponseService extends IntentService { number = URLDecoder.decode(number); } - Address address = Address.fromExternal(this, number); - Recipient recipient = Recipient.from(this, address, false); - int subscriptionId = recipient.getDefaultSubscriptionId().or(-1); - long expiresIn = recipient.getExpireMessages() * 1000L; - if (!TextUtils.isEmpty(content)) { - MessageSender.send(this, new OutgoingTextMessage(recipient, content, expiresIn, subscriptionId), -1, false, null); + VisibleMessage message = new VisibleMessage(); + message.setText(content); + message.setSentTimestamp(System.currentTimeMillis()); + MessageSender.send(message, Address.fromExternal(this, number)); } } catch (URISyntaxException e) { Toast.makeText(this, R.string.QuickResponseService_problem_sending_message, Toast.LENGTH_LONG).show(); diff --git a/app/src/main/java/org/thoughtcrime/securesms/sms/MessageSender.java b/app/src/main/java/org/thoughtcrime/securesms/sms/MessageSender.java deleted file mode 100644 index a1ff5dcd79..0000000000 --- a/app/src/main/java/org/thoughtcrime/securesms/sms/MessageSender.java +++ /dev/null @@ -1,213 +0,0 @@ -/* - * Copyright (C) 2011 Whisper Systems - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ -package org.thoughtcrime.securesms.sms; - -import android.content.Context; -import androidx.annotation.NonNull; - -import org.thoughtcrime.securesms.ApplicationContext; -import org.session.libsession.messaging.sending_receiving.attachments.Attachment; -import org.session.libsession.messaging.threads.Address; -import org.thoughtcrime.securesms.database.AttachmentDatabase; -import org.thoughtcrime.securesms.database.DatabaseFactory; -import org.thoughtcrime.securesms.database.MessagingDatabase.SyncMessageId; -import org.thoughtcrime.securesms.database.MmsDatabase; -import org.thoughtcrime.securesms.database.MmsSmsDatabase; -import org.thoughtcrime.securesms.database.NoSuchMessageException; -import org.thoughtcrime.securesms.database.SmsDatabase; -import org.thoughtcrime.securesms.database.ThreadDatabase; -import org.thoughtcrime.securesms.database.model.MessageRecord; -import org.thoughtcrime.securesms.database.model.SmsMessageRecord; -import org.thoughtcrime.securesms.jobmanager.JobManager; -import org.thoughtcrime.securesms.jobs.PushGroupSendJob; -import org.thoughtcrime.securesms.jobs.PushMediaSendJob; -import org.thoughtcrime.securesms.jobs.PushTextSendJob; -import org.session.libsignal.utilities.logging.Log; -import org.thoughtcrime.securesms.mms.MmsException; -import org.thoughtcrime.securesms.mms.OutgoingMediaMessage; -import org.session.libsession.messaging.threads.recipients.Recipient; -import org.thoughtcrime.securesms.service.ExpiringMessageManager; -import org.session.libsession.utilities.TextSecurePreferences; - -public class MessageSender { - - private static final String TAG = MessageSender.class.getSimpleName(); - - public static long send(final Context context, - final OutgoingTextMessage message, - final long threadId, - final boolean forceSms, - final SmsDatabase.InsertListener insertListener) - { - SmsDatabase database = DatabaseFactory.getSmsDatabase(context); - Recipient recipient = message.getRecipient(); - - long allocatedThreadId; - - if (threadId == -1) { - allocatedThreadId = DatabaseFactory.getThreadDatabase(context).getOrCreateThreadIdFor(recipient); - } else { - allocatedThreadId = threadId; - } - - long messageId = database.insertMessageOutbox(allocatedThreadId, message, forceSms, System.currentTimeMillis(), insertListener); - - sendTextMessage(context, recipient, forceSms, messageId); - - return allocatedThreadId; - } - - public static long send(final Context context, - final OutgoingMediaMessage message, - final long threadId, - final boolean forceSms, - final SmsDatabase.InsertListener insertListener) - { - try { - ThreadDatabase threadDatabase = DatabaseFactory.getThreadDatabase(context); - MmsDatabase database = DatabaseFactory.getMmsDatabase(context); - - long allocatedThreadId; - - if (threadId == -1) { - allocatedThreadId = threadDatabase.getOrCreateThreadIdFor(message.getRecipient(), message.getDistributionType()); - } else { - allocatedThreadId = threadId; - } - - Recipient recipient = message.getRecipient(); - long messageId = database.insertMessageOutbox(message, allocatedThreadId, forceSms, insertListener); - - sendMediaMessage(context, recipient, forceSms, messageId, message.getExpiresIn()); - return allocatedThreadId; - } catch (MmsException e) { - Log.w(TAG, e); - return threadId; - } - } - - public static void resend(Context context, MessageRecord messageRecord) { - long messageId = messageRecord.getId(); - boolean forceSms = messageRecord.isForcedSms(); - long expiresIn = messageRecord.getExpiresIn(); - Recipient recipient = messageRecord.getRecipient(); - - if (messageRecord.isMms()) { - sendMediaMessage(context, recipient, forceSms, messageId, expiresIn); - } else { - sendTextMessage(context, recipient, forceSms, messageId); - } - } - - private static void sendMediaMessage(Context context, Recipient recipient, boolean forceSms, long messageId, long expiresIn) - { - if (isLocalSelfSend(context, recipient, forceSms)) { - sendLocalMediaSelf(context, messageId); - } else if (isGroupPushSend(recipient)) { - sendGroupPush(context, recipient, messageId, null); - } else { - sendMediaPush(context, recipient, messageId); - } - } - - private static void sendTextMessage(Context context, Recipient recipient, - boolean forceSms, long messageId) - { - if (isLocalSelfSend(context, recipient, forceSms)) { - sendLocalTextSelf(context, messageId); - } else { - sendTextPush(context, recipient, messageId); - } - } - - private static void sendTextPush(Context context, Recipient recipient, long messageId) { - JobManager jobManager = ApplicationContext.getInstance(context).getJobManager(); - jobManager.add(new PushTextSendJob(messageId, recipient.getAddress())); - } - - private static void sendMediaPush(Context context, Recipient recipient, long messageId) { - JobManager jobManager = ApplicationContext.getInstance(context).getJobManager(); - PushMediaSendJob.enqueue(context, jobManager, messageId, recipient.getAddress()); - } - - private static void sendGroupPush(Context context, Recipient recipient, long messageId, Address filterAddress) { - JobManager jobManager = ApplicationContext.getInstance(context).getJobManager(); - PushGroupSendJob.enqueue(context, jobManager, messageId, recipient.getAddress(), filterAddress); - } - - private static boolean isGroupPushSend(Recipient recipient) { - return recipient.getAddress().isGroup() && - !recipient.getAddress().isMmsGroup(); - } - - private static boolean isLocalSelfSend(@NonNull Context context, @NonNull Recipient recipient, boolean forceSms) { - return recipient.isLocalNumber() && - !forceSms && - TextSecurePreferences.isPushRegistered(context); - } - - private static void sendLocalMediaSelf(Context context, long messageId) { - try { - ExpiringMessageManager expirationManager = ApplicationContext.getInstance(context).getExpiringMessageManager(); - AttachmentDatabase attachmentDatabase = DatabaseFactory.getAttachmentDatabase(context); - MmsDatabase mmsDatabase = DatabaseFactory.getMmsDatabase(context); - MmsSmsDatabase mmsSmsDatabase = DatabaseFactory.getMmsSmsDatabase(context); - OutgoingMediaMessage message = mmsDatabase.getOutgoingMessage(messageId); - SyncMessageId syncId = new SyncMessageId(Address.fromSerialized(TextSecurePreferences.getLocalNumber(context)), message.getSentTimeMillis()); - - for (Attachment attachment : message.getAttachments()) { - attachmentDatabase.markAttachmentUploaded(messageId, attachment); - } - - mmsDatabase.markAsSent(messageId, true); - mmsDatabase.markUnidentified(messageId, true); - - mmsSmsDatabase.incrementDeliveryReceiptCount(syncId, System.currentTimeMillis()); - mmsSmsDatabase.incrementReadReceiptCount(syncId, System.currentTimeMillis()); - - if (message.getExpiresIn() > 0 && !message.isExpirationUpdate()) { - mmsDatabase.markExpireStarted(messageId); - expirationManager.scheduleDeletion(messageId, true, message.getExpiresIn()); - } - } catch (NoSuchMessageException | MmsException e) { - Log.w("Failed to update self-sent message.", e); - } - } - - private static void sendLocalTextSelf(Context context, long messageId) { - try { - ExpiringMessageManager expirationManager = ApplicationContext.getInstance(context).getExpiringMessageManager(); - SmsDatabase smsDatabase = DatabaseFactory.getSmsDatabase(context); - MmsSmsDatabase mmsSmsDatabase = DatabaseFactory.getMmsSmsDatabase(context); - SmsMessageRecord message = smsDatabase.getMessage(messageId); - SyncMessageId syncId = new SyncMessageId(Address.fromSerialized(TextSecurePreferences.getLocalNumber(context)), message.getDateSent()); - - smsDatabase.markAsSent(messageId, true); - smsDatabase.markUnidentified(messageId, true); - - mmsSmsDatabase.incrementDeliveryReceiptCount(syncId, System.currentTimeMillis()); - mmsSmsDatabase.incrementReadReceiptCount(syncId, System.currentTimeMillis()); - - if (message.getExpiresIn() > 0) { - smsDatabase.markExpireStarted(messageId); - expirationManager.scheduleDeletion(message.getId(), message.isMms(), message.getExpiresIn()); - } - } catch (NoSuchMessageException e) { - Log.w("Failed to update self-sent message.", e); - } - } -} diff --git a/app/src/main/java/org/thoughtcrime/securesms/sms/OutgoingEncryptedMessage.java b/app/src/main/java/org/thoughtcrime/securesms/sms/OutgoingEncryptedMessage.java deleted file mode 100644 index 6d64c7140e..0000000000 --- a/app/src/main/java/org/thoughtcrime/securesms/sms/OutgoingEncryptedMessage.java +++ /dev/null @@ -1,15 +0,0 @@ -package org.thoughtcrime.securesms.sms; - -import org.session.libsession.messaging.threads.recipients.Recipient; - -public class OutgoingEncryptedMessage extends OutgoingTextMessage { - - public OutgoingEncryptedMessage(Recipient recipient, String body, long expiresIn) { - super(recipient, body, expiresIn, -1); - } - - @Override - public boolean isSecureMessage() { - return true; - } -} diff --git a/app/src/main/java/org/thoughtcrime/securesms/database/documents/Document.java b/libsession/src/main/java/org/session/libsession/database/documents/Document.java similarity index 66% rename from app/src/main/java/org/thoughtcrime/securesms/database/documents/Document.java rename to libsession/src/main/java/org/session/libsession/database/documents/Document.java index 2b226f66da..2167e0ee2a 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/database/documents/Document.java +++ b/libsession/src/main/java/org/session/libsession/database/documents/Document.java @@ -1,4 +1,4 @@ -package org.thoughtcrime.securesms.database.documents; +package org.session.libsession.database.documents; import java.util.List; diff --git a/app/src/main/java/org/thoughtcrime/securesms/database/documents/IdentityKeyMismatch.java b/libsession/src/main/java/org/session/libsession/database/documents/IdentityKeyMismatch.java similarity index 98% rename from app/src/main/java/org/thoughtcrime/securesms/database/documents/IdentityKeyMismatch.java rename to libsession/src/main/java/org/session/libsession/database/documents/IdentityKeyMismatch.java index 075996f030..3140ba2bdf 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/database/documents/IdentityKeyMismatch.java +++ b/libsession/src/main/java/org/session/libsession/database/documents/IdentityKeyMismatch.java @@ -1,4 +1,4 @@ -package org.thoughtcrime.securesms.database.documents; +package org.session.libsession.database.documents; import org.session.libsignal.utilities.logging.Log; diff --git a/app/src/main/java/org/thoughtcrime/securesms/database/documents/IdentityKeyMismatchList.java b/libsession/src/main/java/org/session/libsession/database/documents/IdentityKeyMismatchList.java similarity index 93% rename from app/src/main/java/org/thoughtcrime/securesms/database/documents/IdentityKeyMismatchList.java rename to libsession/src/main/java/org/session/libsession/database/documents/IdentityKeyMismatchList.java index eaceb4d93f..e270522de6 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/database/documents/IdentityKeyMismatchList.java +++ b/libsession/src/main/java/org/session/libsession/database/documents/IdentityKeyMismatchList.java @@ -1,4 +1,4 @@ -package org.thoughtcrime.securesms.database.documents; +package org.session.libsession.database.documents; import com.fasterxml.jackson.annotation.JsonIgnore; import com.fasterxml.jackson.annotation.JsonProperty; diff --git a/app/src/main/java/org/thoughtcrime/securesms/database/documents/NetworkFailure.java b/libsession/src/main/java/org/session/libsession/database/documents/NetworkFailure.java similarity index 93% rename from app/src/main/java/org/thoughtcrime/securesms/database/documents/NetworkFailure.java rename to libsession/src/main/java/org/session/libsession/database/documents/NetworkFailure.java index ce16b50ff8..993cf6f832 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/database/documents/NetworkFailure.java +++ b/libsession/src/main/java/org/session/libsession/database/documents/NetworkFailure.java @@ -1,4 +1,4 @@ -package org.thoughtcrime.securesms.database.documents; +package org.session.libsession.database.documents; import com.fasterxml.jackson.annotation.JsonIgnore; import com.fasterxml.jackson.annotation.JsonProperty; diff --git a/app/src/main/java/org/thoughtcrime/securesms/database/documents/NetworkFailureList.java b/libsession/src/main/java/org/session/libsession/database/documents/NetworkFailureList.java similarity index 92% rename from app/src/main/java/org/thoughtcrime/securesms/database/documents/NetworkFailureList.java rename to libsession/src/main/java/org/session/libsession/database/documents/NetworkFailureList.java index 3347c42846..9fdea4d7d3 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/database/documents/NetworkFailureList.java +++ b/libsession/src/main/java/org/session/libsession/database/documents/NetworkFailureList.java @@ -1,4 +1,4 @@ -package org.thoughtcrime.securesms.database.documents; +package org.session.libsession.database.documents; import com.fasterxml.jackson.annotation.JsonIgnore; import com.fasterxml.jackson.annotation.JsonProperty; 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 e3062f73ee..bd94250598 100644 --- a/libsession/src/main/java/org/session/libsession/messaging/StorageProtocol.kt +++ b/libsession/src/main/java/org/session/libsession/messaging/StorageProtocol.kt @@ -95,8 +95,8 @@ interface StorageProtocol { fun getMessageIdInDatabase(timestamp: Long, author: String): Long? fun setOpenGroupServerMessageID(messageID: Long, serverID: Long) - fun markAsSent(messageID: Long) - fun markUnidentified(messageID: Long) + fun markAsSent(timestamp: Long, author: String) + fun markUnidentified(timestamp: Long, author: String) fun setErrorMessage(messageID: Long, error: Exception) // Closed Groups diff --git a/libsession/src/main/java/org/session/libsession/messaging/jobs/AttachmentUploadJob.kt b/libsession/src/main/java/org/session/libsession/messaging/jobs/AttachmentUploadJob.kt index e9c8c7d01d..e507be5d65 100644 --- a/libsession/src/main/java/org/session/libsession/messaging/jobs/AttachmentUploadJob.kt +++ b/libsession/src/main/java/org/session/libsession/messaging/jobs/AttachmentUploadJob.kt @@ -28,7 +28,7 @@ class AttachmentUploadJob(val attachmentID: Long, val threadID: String, val mess // Settings override val maxFailureCount: Int = 20 companion object { - val TAG = AttachmentUploadJob::class.qualifiedName + val TAG = AttachmentUploadJob::class.simpleName val KEY: String = "AttachmentUploadJob" val maxFailureCount: Int = 20 diff --git a/libsession/src/main/java/org/session/libsession/messaging/jobs/MessageReceiveJob.kt b/libsession/src/main/java/org/session/libsession/messaging/jobs/MessageReceiveJob.kt index d6b2bfff8f..fd92707065 100644 --- a/libsession/src/main/java/org/session/libsession/messaging/jobs/MessageReceiveJob.kt +++ b/libsession/src/main/java/org/session/libsession/messaging/jobs/MessageReceiveJob.kt @@ -15,8 +15,8 @@ class MessageReceiveJob(val data: ByteArray, val isBackgroundPoll: Boolean, val // Settings override val maxFailureCount: Int = 10 companion object { - val TAG = MessageReceiveJob::class.qualifiedName - val KEY: String = "AttachmentUploadJob" + val TAG = MessageReceiveJob::class.simpleName + val KEY: String = "MessageReceiveJob" //keys used for database storage purpose private val KEY_DATA = "data" diff --git a/libsession/src/main/java/org/session/libsession/messaging/jobs/MessageSendJob.kt b/libsession/src/main/java/org/session/libsession/messaging/jobs/MessageSendJob.kt index e00e0a43a5..4ce92c1153 100644 --- a/libsession/src/main/java/org/session/libsession/messaging/jobs/MessageSendJob.kt +++ b/libsession/src/main/java/org/session/libsession/messaging/jobs/MessageSendJob.kt @@ -19,7 +19,7 @@ class MessageSendJob(val message: Message, val destination: Destination) : Job { // Settings override val maxFailureCount: Int = 10 companion object { - val TAG = MessageSendJob::class.qualifiedName + val TAG = MessageSendJob::class.simpleName val KEY: String = "MessageSendJob" //keys used for database storage purpose 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 2cf27ed8ed..9944e53cec 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 @@ -18,8 +18,12 @@ abstract class Message { // validation open fun isValid(): Boolean { - sentTimestamp = if (sentTimestamp!! > 0) sentTimestamp else return false - receivedTimestamp = if (receivedTimestamp!! > 0) receivedTimestamp else return false + sentTimestamp?.let { + if (it <= 0) return false + } + receivedTimestamp?.let { + if (it <= 0) return false + } return sender != null && recipient != null } diff --git a/libsession/src/main/java/org/session/libsession/messaging/messages/control/ExpirationTimerUpdate.kt b/libsession/src/main/java/org/session/libsession/messaging/messages/control/ExpirationTimerUpdate.kt index 09b4f4e3d6..a1c8e6b775 100644 --- a/libsession/src/main/java/org/session/libsession/messaging/messages/control/ExpirationTimerUpdate.kt +++ b/libsession/src/main/java/org/session/libsession/messaging/messages/control/ExpirationTimerUpdate.kt @@ -5,6 +5,7 @@ import org.session.libsignal.service.internal.push.SignalServiceProtos class ExpirationTimerUpdate() : ControlMessage() { + var syncTarget: String? = null var duration: Int? = 0 companion object { @@ -12,7 +13,7 @@ class ExpirationTimerUpdate() : ControlMessage() { fun fromProto(proto: SignalServiceProtos.Content): ExpirationTimerUpdate? { val dataMessageProto = proto.dataMessage ?: return null - val isExpirationTimerUpdate = (dataMessageProto.flags and SignalServiceProtos.DataMessage.Flags.EXPIRATION_TIMER_UPDATE_VALUE) != 0 //TODO validate that 'and' operator equivalent to Swift '&' + val isExpirationTimerUpdate = dataMessageProto.flags.and(SignalServiceProtos.DataMessage.Flags.EXPIRATION_TIMER_UPDATE_VALUE) != 0 if (!isExpirationTimerUpdate) return null val duration = dataMessageProto.expireTimer return ExpirationTimerUpdate(duration) diff --git a/app/src/main/java/org/thoughtcrime/securesms/sms/IncomingEncryptedMessage.java b/libsession/src/main/java/org/session/libsession/messaging/messages/signal/IncomingEncryptedMessage.java similarity index 81% rename from app/src/main/java/org/thoughtcrime/securesms/sms/IncomingEncryptedMessage.java rename to libsession/src/main/java/org/session/libsession/messaging/messages/signal/IncomingEncryptedMessage.java index 66586a68b9..f5a63d4ac5 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/sms/IncomingEncryptedMessage.java +++ b/libsession/src/main/java/org/session/libsession/messaging/messages/signal/IncomingEncryptedMessage.java @@ -1,4 +1,4 @@ -package org.thoughtcrime.securesms.sms; +package org.session.libsession.messaging.messages.signal; public class IncomingEncryptedMessage extends IncomingTextMessage { diff --git a/app/src/main/java/org/thoughtcrime/securesms/sms/IncomingGroupMessage.java b/libsession/src/main/java/org/session/libsession/messaging/messages/signal/IncomingGroupMessage.java similarity index 91% rename from app/src/main/java/org/thoughtcrime/securesms/sms/IncomingGroupMessage.java rename to libsession/src/main/java/org/session/libsession/messaging/messages/signal/IncomingGroupMessage.java index af17d4b963..b0a7de08ee 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/sms/IncomingGroupMessage.java +++ b/libsession/src/main/java/org/session/libsession/messaging/messages/signal/IncomingGroupMessage.java @@ -1,4 +1,4 @@ -package org.thoughtcrime.securesms.sms; +package org.session.libsession.messaging.messages.signal; import static org.session.libsignal.service.internal.push.SignalServiceProtos.GroupContext; diff --git a/app/src/main/java/org/thoughtcrime/securesms/sms/IncomingTextMessage.java b/libsession/src/main/java/org/session/libsession/messaging/messages/signal/IncomingTextMessage.java similarity index 96% rename from app/src/main/java/org/thoughtcrime/securesms/sms/IncomingTextMessage.java rename to libsession/src/main/java/org/session/libsession/messaging/messages/signal/IncomingTextMessage.java index 0acf91c242..31be71cf3d 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/sms/IncomingTextMessage.java +++ b/libsession/src/main/java/org/session/libsession/messaging/messages/signal/IncomingTextMessage.java @@ -1,20 +1,14 @@ -package org.thoughtcrime.securesms.sms; +package org.session.libsession.messaging.messages.signal; -import android.content.Context; import android.os.Parcel; import android.os.Parcelable; -import androidx.annotation.NonNull; import androidx.annotation.Nullable; -import android.telephony.SmsMessage; import org.session.libsession.messaging.messages.visible.VisibleMessage; import org.session.libsession.messaging.threads.Address; import org.session.libsession.utilities.GroupUtil; import org.session.libsignal.libsignal.util.guava.Optional; import org.session.libsignal.service.api.messages.SignalServiceGroup; -import org.session.libsignal.service.api.push.SignalServiceAddress; - -import java.util.List; public class IncomingTextMessage implements Parcelable { diff --git a/app/src/main/java/org/thoughtcrime/securesms/sms/OutgoingTextMessage.java b/libsession/src/main/java/org/session/libsession/messaging/messages/signal/OutgoingTextMessage.java similarity index 69% rename from app/src/main/java/org/thoughtcrime/securesms/sms/OutgoingTextMessage.java rename to libsession/src/main/java/org/session/libsession/messaging/messages/signal/OutgoingTextMessage.java index dca0af749e..0d3cd92aa9 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/sms/OutgoingTextMessage.java +++ b/libsession/src/main/java/org/session/libsession/messaging/messages/signal/OutgoingTextMessage.java @@ -1,7 +1,6 @@ -package org.thoughtcrime.securesms.sms; +package org.session.libsession.messaging.messages.signal; import org.session.libsession.messaging.messages.visible.VisibleMessage; -import org.thoughtcrime.securesms.database.model.SmsMessageRecord; import org.session.libsession.messaging.threads.recipients.Recipient; public class OutgoingTextMessage { @@ -39,14 +38,6 @@ public class OutgoingTextMessage { } public boolean isSecureMessage() { - return false; - } - - public static OutgoingTextMessage from(SmsMessageRecord record) { - if (record.isSecure()) { - return new OutgoingEncryptedMessage(record.getRecipient(), record.getBody(), record.getExpiresIn()); - } else { - return new OutgoingTextMessage(record.getRecipient(), record.getBody(), record.getExpiresIn(), record.getSubscriptionId()); - } + return true; } } diff --git a/libsession/src/main/java/org/session/libsession/messaging/messages/visible/Attachment.kt b/libsession/src/main/java/org/session/libsession/messaging/messages/visible/Attachment.kt index df292c65f8..3e21e8303c 100644 --- a/libsession/src/main/java/org/session/libsession/messaging/messages/visible/Attachment.kt +++ b/libsession/src/main/java/org/session/libsession/messaging/messages/visible/Attachment.kt @@ -32,7 +32,7 @@ class Attachment { result.contentType = proto.contentType ?: inferContentType() result.key = proto.key.toByteArray() result.digest = proto.digest.toByteArray() - val kind: Kind = if (proto.hasFlags() && (proto.flags and SignalServiceProtos.AttachmentPointer.Flags.VOICE_MESSAGE_VALUE) > 0) { //TODO validate that 'and' operator = swift '&' + val kind: Kind = if (proto.hasFlags() && proto.flags.and(SignalServiceProtos.AttachmentPointer.Flags.VOICE_MESSAGE_VALUE) > 0) { Kind.VOICE_MESSAGE } else { Kind.GENERIC @@ -42,7 +42,7 @@ class Attachment { val size: Size = if (proto.hasWidth() && proto.width > 0 && proto.hasHeight() && proto.height > 0) { Size(proto.width, proto.height) } else { - Size(0,0) //TODO check that it's equivalent to swift: CGSize.zero + Size(0,0) } result.size = size result.sizeInBytes = if (proto.size > 0) proto.size else null diff --git a/libsession/src/main/java/org/session/libsession/messaging/messages/visible/LinkPreview.kt b/libsession/src/main/java/org/session/libsession/messaging/messages/visible/LinkPreview.kt index c62d0685bb..d48681355f 100644 --- a/libsession/src/main/java/org/session/libsession/messaging/messages/visible/LinkPreview.kt +++ b/libsession/src/main/java/org/session/libsession/messaging/messages/visible/LinkPreview.kt @@ -1,6 +1,7 @@ package org.session.libsession.messaging.messages.visible import org.session.libsession.messaging.MessagingConfiguration +import org.session.libsession.messaging.sending_receiving.linkpreview.LinkPreview as SignalLinkPreiview import org.session.libsignal.utilities.logging.Log import org.session.libsignal.service.internal.push.SignalServiceProtos @@ -18,6 +19,14 @@ class LinkPreview() { val url = proto.url return LinkPreview(title, url, null) } + + fun from(signalLinkPreview: SignalLinkPreiview?): LinkPreview? { + return if (signalLinkPreview == null) { + null + } else { + LinkPreview(signalLinkPreview.title, signalLinkPreview.url, signalLinkPreview.attachmentId?.rowId) + } + } } //constructor diff --git a/libsession/src/main/java/org/session/libsession/messaging/messages/visible/Quote.kt b/libsession/src/main/java/org/session/libsession/messaging/messages/visible/Quote.kt index 71f76a09e4..7b735fcb2b 100644 --- a/libsession/src/main/java/org/session/libsession/messaging/messages/visible/Quote.kt +++ b/libsession/src/main/java/org/session/libsession/messaging/messages/visible/Quote.kt @@ -2,6 +2,8 @@ package org.session.libsession.messaging.messages.visible import com.goterl.lazycode.lazysodium.BuildConfig import org.session.libsession.messaging.MessagingConfiguration +import org.session.libsession.messaging.sending_receiving.attachments.DatabaseAttachment +import org.session.libsession.messaging.sending_receiving.quotes.QuoteModel as SignalQuote import org.session.libsignal.utilities.logging.Log import org.session.libsignal.service.internal.push.SignalServiceProtos @@ -21,6 +23,15 @@ class Quote() { val text = proto.text return Quote(timestamp, publicKey, text, null) } + + fun from(signalQuote: SignalQuote?): Quote? { + return if (signalQuote == null) { + null + } else { + val attachmentID = (signalQuote.attachments?.firstOrNull() as? DatabaseAttachment)?.attachmentId?.rowId + Quote(signalQuote.id, signalQuote.author.serialize(), signalQuote.text, attachmentID) + } + } } //constructor diff --git a/libsession/src/main/java/org/session/libsession/messaging/messages/visible/VisibleMessage.kt b/libsession/src/main/java/org/session/libsession/messaging/messages/visible/VisibleMessage.kt index 0f5f283c73..2748d01d29 100644 --- a/libsession/src/main/java/org/session/libsession/messaging/messages/visible/VisibleMessage.kt +++ b/libsession/src/main/java/org/session/libsession/messaging/messages/visible/VisibleMessage.kt @@ -4,6 +4,8 @@ import com.goterl.lazycode.lazysodium.BuildConfig import org.session.libsession.messaging.MessagingConfiguration import org.session.libsession.messaging.messages.Message +import org.session.libsession.messaging.sending_receiving.attachments.DatabaseAttachment +import org.session.libsession.messaging.sending_receiving.attachments.Attachment as SignalAttachment import org.session.libsignal.utilities.logging.Log import org.session.libsignal.service.internal.push.SignalServiceProtos @@ -46,6 +48,14 @@ class VisibleMessage : Message() { } } + fun addSignalAttachments(signalAttachments: List) { + val attachmentIDs = signalAttachments.map { + val databaseAttachment = it as DatabaseAttachment + databaseAttachment.attachmentId.rowId + } + this.attachmentIDs = attachmentIDs as ArrayList + } + fun isMediaMessage(): Boolean { return attachmentIDs.isNotEmpty() || quote != null || linkPreview != null || contact != null } 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 044683f155..b105d1fa6f 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 @@ -5,27 +5,31 @@ 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.MessageSendJob 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.control.ClosedGroupControlMessage import org.session.libsession.messaging.messages.control.ConfigurationMessage -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.messages.control.ExpirationTimerUpdate +import org.session.libsession.messaging.messages.visible.* +import org.session.libsession.messaging.sending_receiving.attachments.Attachment as SignalAttachment +import org.session.libsession.messaging.sending_receiving.linkpreview.LinkPreview as SignalLinkPreview +import org.session.libsession.messaging.sending_receiving.quotes.QuoteModel as SignalQuote import org.session.libsession.messaging.opengroups.OpenGroupAPI import org.session.libsession.messaging.opengroups.OpenGroupMessage +import org.session.libsession.messaging.threads.Address import org.session.libsession.messaging.utilities.MessageWrapper import org.session.libsession.snode.RawResponsePromise import org.session.libsession.snode.SnodeAPI +import org.session.libsession.snode.SnodeConfiguration import org.session.libsession.snode.SnodeMessage import org.session.libsession.utilities.SSKEnvironment -import org.session.libsignal.utilities.logging.Log -import org.session.libsignal.service.api.messages.SignalServiceAttachment import org.session.libsignal.service.internal.push.SignalServiceProtos -import org.session.libsignal.utilities.Base64 import org.session.libsignal.service.loki.api.crypto.ProofOfWork import org.session.libsignal.service.loki.utilities.hexEncodedPublicKey +import org.session.libsignal.utilities.Base64 +import org.session.libsignal.utilities.logging.Log object MessageSender { @@ -56,25 +60,22 @@ object MessageSender { } // Preparation - fun prep(signalAttachments: List, message: VisibleMessage) { - // TODO: Deal with SignalServiceAttachmentStream + fun prep(signalAttachments: List, message: VisibleMessage) { val attachments = mutableListOf() for (signalAttachment in signalAttachments) { val attachment = Attachment() - if (signalAttachment.isPointer) { - val signalAttachmentPointer = signalAttachment.asPointer() - attachment.fileName = signalAttachmentPointer.fileName.orNull() - attachment.caption = signalAttachmentPointer.caption.orNull() - attachment.contentType = signalAttachmentPointer.contentType - attachment.digest = signalAttachmentPointer.digest.orNull() - attachment.key = signalAttachmentPointer.key - attachment.sizeInBytes = signalAttachmentPointer.size.orNull() - attachment.url = signalAttachmentPointer.url - attachment.size = Size(signalAttachmentPointer.width, signalAttachmentPointer.height) - attachments.add(attachment) - } + attachment.fileName = signalAttachment.fileName + attachment.caption = signalAttachment.caption + attachment.contentType = signalAttachment.contentType + attachment.digest = signalAttachment.digest + attachment.key = Base64.decode(signalAttachment.key) + attachment.sizeInBytes = signalAttachment.size.toInt() + attachment.url = signalAttachment.url + attachment.size = Size(signalAttachment.width, signalAttachment.height) + attachments.add(attachment) } - val attachmentIDs = MessagingConfiguration.shared.storage.persistAttachments(message.id ?: 0, attachments) + val attachmentIDs = MessagingConfiguration.shared.storage.persistAttachments(message.id + ?: 0, attachments) message.attachmentIDs.addAll(attachmentIDs) } @@ -170,7 +171,7 @@ object MessageSender { val wrappedMessage = MessageWrapper.wrap(kind, message.sentTimestamp!!, senderPublicKey, ciphertext) // Calculate proof of work if (destination is Destination.Contact && message is VisibleMessage && !isSelfSend) { - //TODO Notify user for proof of work calculating + SnodeConfiguration.shared.broadcaster.broadcast("calculatingPoW", message.sentTimestamp!!) } val recipient = message.recipient!! val base64EncodedData = Base64.encodeBytes(wrappedMessage) @@ -178,6 +179,9 @@ object MessageSender { val nonce = ProofOfWork.calculate(base64EncodedData, recipient, timestamp, message.ttl.toInt()) ?: throw Error.ProofOfWorkCalculationFailed // Send the result snodeMessage = SnodeMessage(recipient, base64EncodedData, message.ttl, timestamp, nonce) + if (destination is Destination.Contact && message is VisibleMessage && !isSelfSend) { + SnodeConfiguration.shared.broadcaster.broadcast("sendingMessage", message.sentTimestamp!!) + } SnodeAPI.sendMessage(snodeMessage).success { promises: Set -> var isSuccess = false val promiseCount = promises.size @@ -187,7 +191,7 @@ object MessageSender { if (isSuccess) { return@success } // Succeed as soon as the first promise succeeds isSuccess = true if (destination is Destination.Contact && message is VisibleMessage && !isSelfSend) { - //TODO Notify user for message sent + SnodeConfiguration.shared.broadcaster.broadcast("messageSent", message.sentTimestamp!!) } handleSuccessfulMessageSend(message, destination, isSyncMessage) var shouldNotify = (message is VisibleMessage && !isSyncMessage) @@ -199,7 +203,6 @@ object MessageSender { JobQueue.shared.add(notifyPNServerJob) deferred.resolve(Unit) } - } promise.fail { errorCount += 1 @@ -277,17 +280,19 @@ object MessageSender { storage.setOpenGroupServerMessageID(messageId, message.openGroupServerMessageID!!) } // Mark the message as sent - storage.markAsSent(messageId) - storage.markUnidentified(messageId) + storage.markAsSent(message.sentTimestamp!!, message.sender!!) + storage.markUnidentified(message.sentTimestamp!!, message.sender!!) // Start the disappearing messages timer if needed - SSKEnvironment.shared.messageExpirationManager.startAnyExpiration(messageId) + SSKEnvironment.shared.messageExpirationManager.startAnyExpiration(message.sentTimestamp!!, message.sender!!) // Sync the message if: // • it's a visible message // • the destination was a contact // • we didn't sync it already val userPublicKey = storage.getUserPublicKey()!! - if (destination is Destination.Contact && !isSyncMessage && message is VisibleMessage) { - sendToSnodeDestination(Destination.Contact(userPublicKey), message, true).get() + if (destination is Destination.Contact && !isSyncMessage) { + if (message is VisibleMessage) { message.syncTarget = destination.publicKey } + if (message is ExpirationTimerUpdate) { message.syncTarget = destination.publicKey } + sendToSnodeDestination(Destination.Contact(userPublicKey), message, true) } } @@ -295,5 +300,36 @@ object MessageSender { val storage = MessagingConfiguration.shared.storage val messageId = storage.getMessageIdInDatabase(message.sentTimestamp!!, message.sender!!) ?: return storage.setErrorMessage(messageId, error) + SnodeConfiguration.shared.broadcaster.broadcast("messageFailed", message.sentTimestamp!!) + } + + // Convenience + @JvmStatic + fun send(message: VisibleMessage, address: Address, attachments: List, quote: SignalQuote?, linkPreview: SignalLinkPreview?) { + prep(attachments, message) + message.quote = Quote.from(quote) + message.linkPreview = LinkPreview.from(linkPreview) + send(message, address) + } + + @JvmStatic + fun send(message: Message, address: Address) { + val threadID = MessagingConfiguration.shared.storage.getOrCreateThreadIdFor(address) + message.threadID = threadID + val destination = Destination.from(address) + val job = MessageSendJob(message, destination) + JobQueue.shared.add(job) + } + + fun sendNonDurably(message: VisibleMessage, attachments: List, address: Address): Promise { + prep(attachments, message) + return sendNonDurably(message, address) + } + + fun sendNonDurably(message: Message, address: Address): Promise { + val threadID = MessagingConfiguration.shared.storage.getOrCreateThreadIdFor(address) + message.threadID = threadID + val destination = Destination.from(address) + return send(message, destination) } } \ No newline at end of file diff --git a/libsession/src/main/java/org/session/libsession/messaging/sending_receiving/MessageSenderConvenience.kt b/libsession/src/main/java/org/session/libsession/messaging/sending_receiving/MessageSenderConvenience.kt deleted file mode 100644 index 99d346aeff..0000000000 --- a/libsession/src/main/java/org/session/libsession/messaging/sending_receiving/MessageSenderConvenience.kt +++ /dev/null @@ -1,38 +0,0 @@ -package org.session.libsession.messaging.sending_receiving - -import nl.komponents.kovenant.Promise -import org.session.libsession.messaging.MessagingConfiguration - -import org.session.libsession.messaging.jobs.JobQueue -import org.session.libsession.messaging.jobs.MessageSendJob -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.threads.Address - -import org.session.libsignal.service.api.messages.SignalServiceAttachment - -fun MessageSender.send(message: VisibleMessage, attachments: List, address: Address) { - prep(attachments, message) - send(message, address) -} - -fun MessageSender.send(message: Message, address: Address) { - val threadID = MessagingConfiguration.shared.storage.getOrCreateThreadIdFor(address) - message.threadID = threadID - val destination = Destination.from(address) - val job = MessageSendJob(message, destination) - JobQueue.shared.add(job) -} - -fun MessageSender.sendNonDurably(message: VisibleMessage, attachments: List, address: Address): Promise { - prep(attachments, message) - return sendNonDurably(message, address) -} - -fun MessageSender.sendNonDurably(message: Message, address: Address): Promise { - val threadID = MessagingConfiguration.shared.storage.getOrCreateThreadIdFor(address) - message.threadID = threadID - val destination = Destination.from(address) - return MessageSender.send(message, destination) -} \ No newline at end of file diff --git a/libsession/src/main/java/org/session/libsession/messaging/sending_receiving/attachments/AttachmentId.java b/libsession/src/main/java/org/session/libsession/messaging/sending_receiving/attachments/AttachmentId.java index 7e60f2e77d..1f0f51eece 100644 --- a/libsession/src/main/java/org/session/libsession/messaging/sending_receiving/attachments/AttachmentId.java +++ b/libsession/src/main/java/org/session/libsession/messaging/sending_receiving/attachments/AttachmentId.java @@ -12,10 +12,10 @@ import org.session.libsession.utilities.Util; public class AttachmentId implements Parcelable { @JsonProperty - private final long rowId; + private final long rowId; // This is the field id in the database @JsonProperty - private final long uniqueId; + private final long uniqueId; // This is the timestamp when the attachment is written into the database public AttachmentId(@JsonProperty("rowId") long rowId, @JsonProperty("uniqueId") long uniqueId) { this.rowId = rowId; diff --git a/libsession/src/main/java/org/session/libsession/messaging/sending_receiving/pollers/Poller.kt b/libsession/src/main/java/org/session/libsession/messaging/sending_receiving/pollers/Poller.kt index 007dbbfd60..cdc42be968 100644 --- a/libsession/src/main/java/org/session/libsession/messaging/sending_receiving/pollers/Poller.kt +++ b/libsession/src/main/java/org/session/libsession/messaging/sending_receiving/pollers/Poller.kt @@ -7,10 +7,10 @@ import org.session.libsession.messaging.MessagingConfiguration import org.session.libsession.messaging.jobs.JobQueue import org.session.libsession.messaging.jobs.MessageReceiveJob import org.session.libsession.messaging.utilities.MessageWrapper -import org.session.libsession.snode.Snode import org.session.libsession.snode.SnodeAPI import org.session.libsession.snode.SnodeConfiguration +import org.session.libsignal.service.loki.api.Snode import org.session.libsignal.utilities.logging.Log import org.session.libsignal.utilities.Base64 diff --git a/libsession/src/main/java/org/session/libsession/messaging/threads/DistributionTypes.kt b/libsession/src/main/java/org/session/libsession/messaging/threads/DistributionTypes.kt new file mode 100644 index 0000000000..e71b83b0dd --- /dev/null +++ b/libsession/src/main/java/org/session/libsession/messaging/threads/DistributionTypes.kt @@ -0,0 +1,9 @@ +package org.session.libsession.messaging.threads + +object DistributionTypes { + const val DEFAULT = 2 + const val BROADCAST = 1 + const val CONVERSATION = 2 + const val ARCHIVE = 3 + const val INBOX_ZERO = 4 +} \ No newline at end of file diff --git a/libsession/src/main/java/org/session/libsession/snode/OnionRequestAPI.kt b/libsession/src/main/java/org/session/libsession/snode/OnionRequestAPI.kt index 8ab1c33dc5..20f1fc8d04 100644 --- a/libsession/src/main/java/org/session/libsession/snode/OnionRequestAPI.kt +++ b/libsession/src/main/java/org/session/libsession/snode/OnionRequestAPI.kt @@ -10,7 +10,7 @@ import org.session.libsession.utilities.AESGCM import org.session.libsignal.utilities.logging.Log import org.session.libsignal.utilities.Base64 import org.session.libsignal.utilities.* -import org.session.libsignal.service.loki.api.* +import org.session.libsignal.service.loki.api.Snode import org.session.libsignal.service.loki.api.fileserver.FileServerAPI import org.session.libsignal.service.loki.api.utilities.* import org.session.libsession.utilities.AESGCM.EncryptionResult @@ -74,7 +74,7 @@ object OnionRequestAPI { ) internal sealed class Destination { - class Snode(val snode: org.session.libsession.snode.Snode) : Destination() + class Snode(val snode: org.session.libsignal.service.loki.api.Snode) : Destination() class Server(val host: String, val target: String, val x25519PublicKey: String) : Destination() } diff --git a/libsession/src/main/java/org/session/libsession/snode/Snode.kt b/libsession/src/main/java/org/session/libsession/snode/Snode.kt index 8fd05c5f01..b02582846c 100644 --- a/libsession/src/main/java/org/session/libsession/snode/Snode.kt +++ b/libsession/src/main/java/org/session/libsession/snode/Snode.kt @@ -1,6 +1,6 @@ package org.session.libsession.snode -public class Snode(val address: String, val port: Int, val publicKeySet: KeySet?) { +class Snode(val address: String, val port: Int, val publicKeySet: KeySet?) { val ip: String get() = address.removePrefix("https://") diff --git a/libsession/src/main/java/org/session/libsession/snode/SnodeAPI.kt b/libsession/src/main/java/org/session/libsession/snode/SnodeAPI.kt index c16e3a57a6..1b17a02211 100644 --- a/libsession/src/main/java/org/session/libsession/snode/SnodeAPI.kt +++ b/libsession/src/main/java/org/session/libsession/snode/SnodeAPI.kt @@ -10,6 +10,9 @@ import org.session.libsession.snode.utilities.getRandomElement import org.session.libsignal.utilities.logging.Log import org.session.libsignal.service.loki.api.utilities.HTTP +import org.session.libsignal.service.loki.api.Snode +import org.session.libsignal.service.loki.database.LokiAPIDatabaseProtocol +import org.session.libsignal.service.loki.utilities.Broadcaster import org.session.libsignal.service.loki.utilities.prettifiedDescription import org.session.libsignal.service.loki.utilities.retryIfNeeded import org.session.libsignal.utilities.* @@ -17,10 +20,11 @@ import org.session.libsignal.utilities.* import java.security.SecureRandom object SnodeAPI { - val database = SnodeConfiguration.shared.storage - val broadcaster = SnodeConfiguration.shared.broadcaster + val database: LokiAPIDatabaseProtocol + get() = SnodeConfiguration.shared.storage + val broadcaster: Broadcaster + get() = SnodeConfiguration.shared.broadcaster val sharedContext = Kovenant.createContext() - val messageSendingContext = Kovenant.createContext() val messagePollingContext = Kovenant.createContext() internal var snodeFailureCount: MutableMap = mutableMapOf() @@ -158,7 +162,7 @@ object SnodeAPI { val parameters = mapOf( "pubKey" to publicKey ) return getRandomSnode().bind { invoke(Snode.Method.GetSwarm, it, publicKey, parameters) - }.map(SnodeAPI.sharedContext) { + }.map(sharedContext) { parseSnodes(it).toSet() }.success { database.setSwarm(publicKey, it) @@ -182,19 +186,12 @@ object SnodeAPI { fun sendMessage(message: SnodeMessage): Promise, Exception> { val destination = message.recipient - fun broadcast(event: String) { - val dayInMs: Long = 86400000 - if (message.ttl != dayInMs && message.ttl != 4 * dayInMs) { return } - broadcaster.broadcast(event, message.timestamp) - } - broadcast("calculatingPoW") return retryIfNeeded(maxRetryCount) { - getTargetSnodes(destination).map(messageSendingContext) { swarm -> + getTargetSnodes(destination).map { swarm -> swarm.map { snode -> - broadcast("sendingMessage") val parameters = message.toJSON() retryIfNeeded(maxRetryCount) { - invoke(Snode.Method.SendMessage, snode, destination, parameters).map(messageSendingContext) { rawResponse -> + invoke(Snode.Method.SendMessage, snode, destination, parameters).map { rawResponse -> val json = rawResponse as? Map<*, *> val powDifficulty = json?.get("difficulty") as? Int if (powDifficulty != null) { diff --git a/libsession/src/main/java/org/session/libsession/snode/SnodeConfiguration.kt b/libsession/src/main/java/org/session/libsession/snode/SnodeConfiguration.kt index ba2923cf4f..a5ff44e7ff 100644 --- a/libsession/src/main/java/org/session/libsession/snode/SnodeConfiguration.kt +++ b/libsession/src/main/java/org/session/libsession/snode/SnodeConfiguration.kt @@ -1,12 +1,13 @@ package org.session.libsession.snode +import org.session.libsignal.service.loki.database.LokiAPIDatabaseProtocol import org.session.libsignal.service.loki.utilities.Broadcaster -class SnodeConfiguration(val storage: SnodeStorageProtocol, val broadcaster: Broadcaster) { +class SnodeConfiguration(val storage: LokiAPIDatabaseProtocol, val broadcaster: Broadcaster) { companion object { lateinit var shared: SnodeConfiguration - fun configure(storage: SnodeStorageProtocol, broadcaster: Broadcaster) { + fun configure(storage: LokiAPIDatabaseProtocol, broadcaster: Broadcaster) { if (Companion::shared.isInitialized) { return } shared = SnodeConfiguration(storage, broadcaster) } 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 2a6be307b0..3c4612c412 100644 --- a/libsession/src/main/java/org/session/libsession/utilities/SSKEnvironment.kt +++ b/libsession/src/main/java/org/session/libsession/utilities/SSKEnvironment.kt @@ -38,7 +38,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) + fun startAnyExpiration(timestamp: Long, author: String) } companion object { diff --git a/libsignal/src/main/java/org/session/libsignal/service/api/messages/SendMessageResult.java b/libsignal/src/main/java/org/session/libsignal/service/api/messages/SendMessageResult.java index 9221e4481f..c273eef353 100644 --- a/libsignal/src/main/java/org/session/libsignal/service/api/messages/SendMessageResult.java +++ b/libsignal/src/main/java/org/session/libsignal/service/api/messages/SendMessageResult.java @@ -26,14 +26,6 @@ public class SendMessageResult { return new SendMessageResult(address, null, true, false, null, null); } - public static SendMessageResult unregisteredFailure(SignalServiceAddress address) { - return new SendMessageResult(address, null, false, true, null, null); - } - - public static SendMessageResult identityFailure(SignalServiceAddress address, IdentityKey identityKey) { - return new SendMessageResult(address, null, false, false, new IdentityFailure(identityKey), null); - } - public SignalServiceAddress getAddress() { return address; } diff --git a/libsignal/src/main/java/org/session/libsignal/service/loki/api/Snode.kt b/libsignal/src/main/java/org/session/libsignal/service/loki/api/Snode.kt index 82b6a29d31..72c0eb1d4d 100644 --- a/libsignal/src/main/java/org/session/libsignal/service/loki/api/Snode.kt +++ b/libsignal/src/main/java/org/session/libsignal/service/loki/api/Snode.kt @@ -4,7 +4,7 @@ public class Snode(val address: String, val port: Int, val publicKeySet: KeySet? val ip: String get() = address.removePrefix("https://") - internal enum class Method(val rawValue: String) { + enum class Method(val rawValue: String) { /** * Only supported by snode targets. */