mirror of
https://github.com/oxen-io/session-android.git
synced 2025-08-12 00:47:43 +00:00
hook up sending pipeline & clean
This commit is contained in:
@@ -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);
|
||||
|
@@ -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);
|
||||
}
|
||||
}
|
||||
|
@@ -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
|
||||
|
@@ -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? {
|
||||
|
@@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -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 {
|
||||
|
@@ -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) {
|
||||
|
@@ -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<Slide> 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);
|
||||
}
|
||||
}
|
||||
|
@@ -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<Void>() {
|
||||
Optional.absent(),
|
||||
initiating).addListener(new AssertedSuccessListener<Void>() {
|
||||
@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<Contact> 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<Void> sendMediaMessage(final boolean forceSms,
|
||||
String body,
|
||||
private ListenableFuture<Void> sendMediaMessage(String body,
|
||||
SlideDeck slideDeck,
|
||||
QuoteModel quote,
|
||||
List<Contact> contacts,
|
||||
List<LinkPreview> previews,
|
||||
final long expiresIn,
|
||||
final int subscriptionId,
|
||||
final boolean initiating,
|
||||
final boolean clearComposeBox)
|
||||
Optional<LinkPreview> linkPreview,
|
||||
final boolean initiating)
|
||||
{
|
||||
|
||||
Pair<String, Optional<Slide>> 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<Attachment> 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<Void> 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<Void>() {
|
||||
sendMediaMessage("", slideDeck, inputPanel.getQuote().orNull(), Optional.absent(), initiating).addListener(new AssertedSuccessListener<Void>() {
|
||||
@Override
|
||||
public void onSuccess(Void nothing) {
|
||||
new AsyncTask<Void, Void, Void>() {
|
||||
|
@@ -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<MessageRecord, Void, Void>() {
|
||||
@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);
|
||||
|
@@ -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) {
|
||||
|
@@ -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)
|
||||
|
@@ -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<IdentityKeyMismatch> items = new ArrayList<IdentityKeyMismatch>() {{
|
||||
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,
|
||||
|
@@ -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;
|
||||
|
@@ -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;
|
||||
|
@@ -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)
|
||||
|
@@ -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;
|
||||
|
@@ -1,10 +0,0 @@
|
||||
package org.thoughtcrime.securesms.database.documents;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public interface Document<T> {
|
||||
|
||||
public int size();
|
||||
public List<T> getList();
|
||||
|
||||
}
|
@@ -1,88 +0,0 @@
|
||||
package org.thoughtcrime.securesms.database.documents;
|
||||
|
||||
import org.session.libsignal.utilities.logging.Log;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonIgnore;
|
||||
import com.fasterxml.jackson.annotation.JsonProperty;
|
||||
import com.fasterxml.jackson.core.JsonGenerator;
|
||||
import com.fasterxml.jackson.core.JsonParser;
|
||||
import com.fasterxml.jackson.databind.DeserializationContext;
|
||||
import com.fasterxml.jackson.databind.JsonDeserializer;
|
||||
import com.fasterxml.jackson.databind.JsonSerializer;
|
||||
import com.fasterxml.jackson.databind.SerializerProvider;
|
||||
import com.fasterxml.jackson.databind.annotation.JsonDeserialize;
|
||||
import com.fasterxml.jackson.databind.annotation.JsonSerialize;
|
||||
|
||||
import org.session.libsession.messaging.threads.Address;
|
||||
import org.session.libsignal.utilities.Base64;
|
||||
import org.session.libsignal.libsignal.IdentityKey;
|
||||
import org.session.libsignal.libsignal.InvalidKeyException;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
public class IdentityKeyMismatch {
|
||||
|
||||
private static final String TAG = IdentityKeyMismatch.class.getSimpleName();
|
||||
|
||||
@JsonProperty(value = "a")
|
||||
private String address;
|
||||
|
||||
@JsonProperty(value = "k")
|
||||
@JsonSerialize(using = IdentityKeySerializer.class)
|
||||
@JsonDeserialize(using = IdentityKeyDeserializer.class)
|
||||
private IdentityKey identityKey;
|
||||
|
||||
public IdentityKeyMismatch() {}
|
||||
|
||||
public IdentityKeyMismatch(Address address, IdentityKey identityKey) {
|
||||
this.address = address.serialize();
|
||||
this.identityKey = identityKey;
|
||||
}
|
||||
|
||||
@JsonIgnore
|
||||
public Address getAddress() {
|
||||
return Address.fromSerialized(address);
|
||||
}
|
||||
|
||||
public IdentityKey getIdentityKey() {
|
||||
return identityKey;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object other) {
|
||||
if (other == null || !(other instanceof IdentityKeyMismatch)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
IdentityKeyMismatch that = (IdentityKeyMismatch)other;
|
||||
return that.address.equals(this.address) && that.identityKey.equals(this.identityKey);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return address.hashCode() ^ identityKey.hashCode();
|
||||
}
|
||||
|
||||
private static class IdentityKeySerializer extends JsonSerializer<IdentityKey> {
|
||||
@Override
|
||||
public void serialize(IdentityKey value, JsonGenerator jsonGenerator, SerializerProvider serializers)
|
||||
throws IOException
|
||||
{
|
||||
jsonGenerator.writeString(Base64.encodeBytes(value.serialize()));
|
||||
}
|
||||
}
|
||||
|
||||
private static class IdentityKeyDeserializer extends JsonDeserializer<IdentityKey> {
|
||||
@Override
|
||||
public IdentityKey deserialize(JsonParser jsonParser, DeserializationContext ctxt)
|
||||
throws IOException
|
||||
{
|
||||
try {
|
||||
return new IdentityKey(Base64.decode(jsonParser.getValueAsString()), 0);
|
||||
} catch (InvalidKeyException e) {
|
||||
Log.w(TAG, e);
|
||||
throw new IOException(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@@ -1,33 +0,0 @@
|
||||
package org.thoughtcrime.securesms.database.documents;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonIgnore;
|
||||
import com.fasterxml.jackson.annotation.JsonProperty;
|
||||
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
|
||||
public class IdentityKeyMismatchList implements Document<IdentityKeyMismatch> {
|
||||
|
||||
@JsonProperty(value = "m")
|
||||
private List<IdentityKeyMismatch> mismatches;
|
||||
|
||||
public IdentityKeyMismatchList() {
|
||||
this.mismatches = new LinkedList<>();
|
||||
}
|
||||
|
||||
public IdentityKeyMismatchList(List<IdentityKeyMismatch> mismatches) {
|
||||
this.mismatches = mismatches;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int size() {
|
||||
if (mismatches == null) return 0;
|
||||
else return mismatches.size();
|
||||
}
|
||||
|
||||
@Override
|
||||
@JsonIgnore
|
||||
public List<IdentityKeyMismatch> getList() {
|
||||
return mismatches;
|
||||
}
|
||||
}
|
@@ -1,36 +0,0 @@
|
||||
package org.thoughtcrime.securesms.database.documents;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonIgnore;
|
||||
import com.fasterxml.jackson.annotation.JsonProperty;
|
||||
|
||||
import org.session.libsession.messaging.threads.Address;
|
||||
|
||||
public class NetworkFailure {
|
||||
|
||||
@JsonProperty(value = "a")
|
||||
private String address;
|
||||
|
||||
public NetworkFailure(Address address) {
|
||||
this.address = address.serialize();
|
||||
}
|
||||
|
||||
public NetworkFailure() {}
|
||||
|
||||
@JsonIgnore
|
||||
public Address getAddress() {
|
||||
return Address.fromSerialized(address);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object other) {
|
||||
if (other == null || !(other instanceof NetworkFailure)) return false;
|
||||
|
||||
NetworkFailure that = (NetworkFailure)other;
|
||||
return this.address.equals(that.address);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return address.hashCode();
|
||||
}
|
||||
}
|
@@ -1,33 +0,0 @@
|
||||
package org.thoughtcrime.securesms.database.documents;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonIgnore;
|
||||
import com.fasterxml.jackson.annotation.JsonProperty;
|
||||
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
|
||||
public class NetworkFailureList implements Document<NetworkFailure> {
|
||||
|
||||
@JsonProperty(value = "l")
|
||||
private List<NetworkFailure> failures;
|
||||
|
||||
public NetworkFailureList() {
|
||||
this.failures = new LinkedList<>();
|
||||
}
|
||||
|
||||
public NetworkFailureList(List<NetworkFailure> failures) {
|
||||
this.failures = failures;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int size() {
|
||||
if (failures == null) return 0;
|
||||
else return failures.size();
|
||||
}
|
||||
|
||||
@Override
|
||||
@JsonIgnore
|
||||
public List<NetworkFailure> getList() {
|
||||
return failures;
|
||||
}
|
||||
}
|
@@ -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();
|
||||
|
@@ -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;
|
||||
|
||||
|
@@ -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;
|
||||
}
|
||||
|
@@ -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;
|
||||
|
||||
|
@@ -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;
|
||||
|
||||
|
@@ -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());
|
||||
}
|
||||
}
|
||||
|
@@ -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;
|
||||
|
@@ -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<Recipient> members,
|
||||
@Nullable Bitmap avatar,
|
||||
@Nullable String name,
|
||||
@NonNull Set<Recipient> admins)
|
||||
{
|
||||
final GroupDatabase groupDatabase = DatabaseFactory.getGroupDatabase(context);
|
||||
final Set<Address> memberAddresses = getMemberAddresses(members);
|
||||
final Set<Address> 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<Address> members,
|
||||
@Nullable String groupName,
|
||||
@Nullable byte[] avatar,
|
||||
@NonNull Set<Address> admins)
|
||||
{
|
||||
Attachment avatarAttachment = null;
|
||||
Address groupAddress = Address.fromSerialized(groupId);
|
||||
Recipient groupRecipient = Recipient.from(context, groupAddress, false);
|
||||
|
||||
List<String> numbers = new LinkedList<>();
|
||||
for (Address member : members) {
|
||||
numbers.add(member.serialize());
|
||||
}
|
||||
|
||||
List<String> 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<Address> getMemberAddresses(Collection<Recipient> recipients) {
|
||||
final Set<Address> results = new HashSet<>();
|
||||
for (Recipient recipient : recipients) {
|
||||
results.add(recipient.getAddress());
|
||||
}
|
||||
|
||||
return results;
|
||||
}
|
||||
|
||||
public static class GroupActionResult {
|
||||
private Recipient groupRecipient;
|
||||
private long threadId;
|
||||
|
@@ -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);
|
||||
}
|
||||
|
@@ -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());
|
||||
|
@@ -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;
|
||||
|
@@ -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(),
|
||||
|
@@ -43,13 +43,13 @@ public class LinkPreviewViewModel extends ViewModel {
|
||||
return linkPreviewState.getValue() != null && linkPreviewState.getValue().getLinkPreview().isPresent();
|
||||
}
|
||||
|
||||
public @NonNull List<LinkPreview> getActiveLinkPreviews() {
|
||||
public Optional<LinkPreview> 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();
|
||||
}
|
||||
}
|
||||
|
||||
|
@@ -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<List<String>> {
|
||||
@@ -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)
|
||||
}
|
||||
|
@@ -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()
|
||||
}
|
||||
|
@@ -301,8 +301,6 @@ class EditClosedGroupActivity : PassphraseRequiredActionBarActivity() {
|
||||
loaderContainer.fadeOut()
|
||||
isLoading = false
|
||||
}
|
||||
} else {
|
||||
GroupManager.updateGroup(this, groupID, members, null, name, admins)
|
||||
}
|
||||
}
|
||||
}
|
@@ -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()
|
||||
}
|
||||
|
@@ -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"
|
||||
|
@@ -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
|
||||
|
@@ -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
|
||||
|
@@ -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) {
|
||||
|
@@ -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<Attachment>(), sentTimeMillis,
|
||||
ThreadDatabase.DistributionTypes.CONVERSATION, expiresIn, null, Collections.emptyList(),
|
||||
DistributionTypes.CONVERSATION, expiresIn, null, Collections.emptyList(),
|
||||
Collections.emptyList());
|
||||
}
|
||||
|
||||
|
@@ -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<Attachment>() {{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<Attachment>() {{if (avatar != null) add(avatar);}},
|
||||
sentTime,
|
||||
ThreadDatabase.DistributionTypes.CONVERSATION, expireIn, quote, contacts, previews);
|
||||
DistributionTypes.CONVERSATION, expireIn, quote, contacts, previews);
|
||||
|
||||
this.group = group;
|
||||
}
|
||||
|
@@ -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<LinkPreview> 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<Attachment> attachments,
|
||||
@Nullable QuoteModel outgoingQuote,
|
||||
@NonNull List<LinkPreview> linkPreviews)
|
||||
@Nullable LinkPreview linkPreview)
|
||||
{
|
||||
List<LinkPreview> 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;
|
||||
}
|
||||
|
@@ -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,
|
||||
|
@@ -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<MarkedMessageInfo> messageIds = DatabaseFactory.getThreadDatabase(context).setRead(replyThreadId, true);
|
||||
|
@@ -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<Void, Void, Void>() {
|
||||
@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:
|
||||
|
@@ -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());
|
||||
}
|
||||
}
|
||||
|
||||
|
@@ -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();
|
||||
|
@@ -1,13 +0,0 @@
|
||||
package org.thoughtcrime.securesms.sms;
|
||||
|
||||
public class IncomingEncryptedMessage extends IncomingTextMessage {
|
||||
|
||||
public IncomingEncryptedMessage(IncomingTextMessage base, String newBody) {
|
||||
super(base, newBody);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isSecureMessage() {
|
||||
return true;
|
||||
}
|
||||
}
|
@@ -1,27 +0,0 @@
|
||||
package org.thoughtcrime.securesms.sms;
|
||||
|
||||
import static org.session.libsignal.service.internal.push.SignalServiceProtos.GroupContext;
|
||||
|
||||
public class IncomingGroupMessage extends IncomingTextMessage {
|
||||
|
||||
private final GroupContext groupContext;
|
||||
|
||||
public IncomingGroupMessage(IncomingTextMessage base, GroupContext groupContext, String body) {
|
||||
super(base, body);
|
||||
this.groupContext = groupContext;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isGroup() {
|
||||
return true;
|
||||
}
|
||||
|
||||
public boolean isUpdate() {
|
||||
return groupContext.getType().getNumber() == GroupContext.Type.UPDATE_VALUE;
|
||||
}
|
||||
|
||||
public boolean isQuit() {
|
||||
return groupContext.getType().getNumber() == GroupContext.Type.QUIT_VALUE;
|
||||
}
|
||||
|
||||
}
|
@@ -1,191 +0,0 @@
|
||||
package org.thoughtcrime.securesms.sms;
|
||||
|
||||
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 {
|
||||
|
||||
public static final Parcelable.Creator<IncomingTextMessage> CREATOR = new Parcelable.Creator<IncomingTextMessage>() {
|
||||
@Override
|
||||
public IncomingTextMessage createFromParcel(Parcel in) {
|
||||
return new IncomingTextMessage(in);
|
||||
}
|
||||
|
||||
@Override
|
||||
public IncomingTextMessage[] newArray(int size) {
|
||||
return new IncomingTextMessage[size];
|
||||
}
|
||||
};
|
||||
private static final String TAG = IncomingTextMessage.class.getSimpleName();
|
||||
|
||||
private final String message;
|
||||
private Address sender;
|
||||
private final int senderDeviceId;
|
||||
private final int protocol;
|
||||
private final String serviceCenterAddress;
|
||||
private final boolean replyPathPresent;
|
||||
private final String pseudoSubject;
|
||||
private final long sentTimestampMillis;
|
||||
private final Address groupId;
|
||||
private final boolean push;
|
||||
private final int subscriptionId;
|
||||
private final long expiresInMillis;
|
||||
private final boolean unidentified;
|
||||
|
||||
public IncomingTextMessage(Address sender, int senderDeviceId, long sentTimestampMillis,
|
||||
String encodedBody, Optional<SignalServiceGroup> group,
|
||||
long expiresInMillis, boolean unidentified)
|
||||
{
|
||||
this.message = encodedBody;
|
||||
this.sender = sender;
|
||||
this.senderDeviceId = senderDeviceId;
|
||||
this.protocol = 31337;
|
||||
this.serviceCenterAddress = "GCM";
|
||||
this.replyPathPresent = true;
|
||||
this.pseudoSubject = "";
|
||||
this.sentTimestampMillis = sentTimestampMillis;
|
||||
this.push = true;
|
||||
this.subscriptionId = -1;
|
||||
this.expiresInMillis = expiresInMillis;
|
||||
this.unidentified = unidentified;
|
||||
|
||||
if (group.isPresent()) {
|
||||
this.groupId = Address.fromSerialized(GroupUtil.getEncodedId(group.get()));
|
||||
} else {
|
||||
this.groupId = null;
|
||||
}
|
||||
}
|
||||
|
||||
public IncomingTextMessage(Parcel in) {
|
||||
this.message = in.readString();
|
||||
this.sender = in.readParcelable(IncomingTextMessage.class.getClassLoader());
|
||||
this.senderDeviceId = in.readInt();
|
||||
this.protocol = in.readInt();
|
||||
this.serviceCenterAddress = in.readString();
|
||||
this.replyPathPresent = (in.readInt() == 1);
|
||||
this.pseudoSubject = in.readString();
|
||||
this.sentTimestampMillis = in.readLong();
|
||||
this.groupId = in.readParcelable(IncomingTextMessage.class.getClassLoader());
|
||||
this.push = (in.readInt() == 1);
|
||||
this.subscriptionId = in.readInt();
|
||||
this.expiresInMillis = in.readLong();
|
||||
this.unidentified = in.readInt() == 1;
|
||||
}
|
||||
|
||||
public IncomingTextMessage(IncomingTextMessage base, String newBody) {
|
||||
this.message = newBody;
|
||||
this.sender = base.getSender();
|
||||
this.senderDeviceId = base.getSenderDeviceId();
|
||||
this.protocol = base.getProtocol();
|
||||
this.serviceCenterAddress = base.getServiceCenterAddress();
|
||||
this.replyPathPresent = base.isReplyPathPresent();
|
||||
this.pseudoSubject = base.getPseudoSubject();
|
||||
this.sentTimestampMillis = base.getSentTimestampMillis();
|
||||
this.groupId = base.getGroupId();
|
||||
this.push = base.isPush();
|
||||
this.subscriptionId = base.getSubscriptionId();
|
||||
this.expiresInMillis = base.getExpiresIn();
|
||||
this.unidentified = base.isUnidentified();
|
||||
}
|
||||
|
||||
public static IncomingTextMessage from(VisibleMessage message,
|
||||
Address sender,
|
||||
Optional<SignalServiceGroup> group,
|
||||
long expiresInMillis)
|
||||
{
|
||||
return new IncomingTextMessage(sender, 1, message.getReceivedTimestamp(), message.getText(), group, expiresInMillis, false);
|
||||
}
|
||||
|
||||
public int getSubscriptionId() {
|
||||
return subscriptionId;
|
||||
}
|
||||
|
||||
public long getExpiresIn() {
|
||||
return expiresInMillis;
|
||||
}
|
||||
|
||||
public long getSentTimestampMillis() {
|
||||
return sentTimestampMillis;
|
||||
}
|
||||
|
||||
public String getPseudoSubject() {
|
||||
return pseudoSubject;
|
||||
}
|
||||
|
||||
public String getMessageBody() {
|
||||
return message;
|
||||
}
|
||||
|
||||
public Address getSender() {
|
||||
return sender;
|
||||
}
|
||||
|
||||
public int getSenderDeviceId() {
|
||||
return senderDeviceId;
|
||||
}
|
||||
|
||||
public int getProtocol() {
|
||||
return protocol;
|
||||
}
|
||||
|
||||
public String getServiceCenterAddress() {
|
||||
return serviceCenterAddress;
|
||||
}
|
||||
|
||||
public boolean isReplyPathPresent() {
|
||||
return replyPathPresent;
|
||||
}
|
||||
|
||||
public boolean isSecureMessage() {
|
||||
return false;
|
||||
}
|
||||
|
||||
public boolean isPush() {
|
||||
return push;
|
||||
}
|
||||
|
||||
public @Nullable Address getGroupId() {
|
||||
return groupId;
|
||||
}
|
||||
|
||||
public boolean isGroup() {
|
||||
return false;
|
||||
}
|
||||
|
||||
public boolean isUnidentified() {
|
||||
return unidentified;
|
||||
}
|
||||
@Override
|
||||
public int describeContents() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeToParcel(Parcel out, int flags) {
|
||||
out.writeString(message);
|
||||
out.writeParcelable(sender, flags);
|
||||
out.writeInt(senderDeviceId);
|
||||
out.writeInt(protocol);
|
||||
out.writeString(serviceCenterAddress);
|
||||
out.writeInt(replyPathPresent ? 1 : 0);
|
||||
out.writeString(pseudoSubject);
|
||||
out.writeLong(sentTimestampMillis);
|
||||
out.writeParcelable(groupId, flags);
|
||||
out.writeInt(push ? 1 : 0);
|
||||
out.writeInt(subscriptionId);
|
||||
out.writeInt(unidentified ? 1 : 0);
|
||||
}
|
||||
}
|
@@ -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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
@@ -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;
|
||||
}
|
||||
}
|
@@ -1,52 +0,0 @@
|
||||
package org.thoughtcrime.securesms.sms;
|
||||
|
||||
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 {
|
||||
|
||||
private final Recipient recipient;
|
||||
private final String message;
|
||||
private final int subscriptionId;
|
||||
private final long expiresIn;
|
||||
|
||||
public OutgoingTextMessage(Recipient recipient, String message, long expiresIn, int subscriptionId) {
|
||||
this.recipient = recipient;
|
||||
this.message = message;
|
||||
this.expiresIn = expiresIn;
|
||||
this.subscriptionId = subscriptionId;
|
||||
}
|
||||
|
||||
public static OutgoingTextMessage from(VisibleMessage message, Recipient recipient) {
|
||||
return new OutgoingTextMessage(recipient, message.getText(), recipient.getExpireMessages() * 1000, -1);
|
||||
}
|
||||
|
||||
public long getExpiresIn() {
|
||||
return expiresIn;
|
||||
}
|
||||
|
||||
public int getSubscriptionId() {
|
||||
return subscriptionId;
|
||||
}
|
||||
|
||||
public String getMessageBody() {
|
||||
return message;
|
||||
}
|
||||
|
||||
public Recipient getRecipient() {
|
||||
return recipient;
|
||||
}
|
||||
|
||||
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());
|
||||
}
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user