diff --git a/app/src/main/java/org/thoughtcrime/securesms/jobs/PushMediaSendJob.java b/app/src/main/java/org/thoughtcrime/securesms/jobs/PushMediaSendJob.java index e4af6c43f3..ee062da34f 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/jobs/PushMediaSendJob.java +++ b/app/src/main/java/org/thoughtcrime/securesms/jobs/PushMediaSendJob.java @@ -227,10 +227,8 @@ public class PushMediaSendJob extends PushSendJob { .build(); if (Util.equals(SignalStore.account().getAci(), address.getAci())) { - Optional syncAccess = UnidentifiedAccessUtil.getAccessForSync(context); - SignalServiceSyncMessage syncMessage = buildSelfSendSyncMessage(context, mediaMessage, syncAccess); - - SendMessageResult result = messageSender.sendSyncMessage(syncMessage, syncAccess); + Optional syncAccess = UnidentifiedAccessUtil.getAccessForSync(context); + SendMessageResult result = messageSender.sendSyncMessage(mediaMessage); SignalDatabase.messageLog().insertIfPossible(messageRecipient.getId(), message.getSentTimeMillis(), result, ContentHint.RESENDABLE, new MessageId(messageId, true)); return syncAccess.isPresent(); } else { diff --git a/app/src/main/java/org/thoughtcrime/securesms/jobs/PushSendJob.java b/app/src/main/java/org/thoughtcrime/securesms/jobs/PushSendJob.java index 790399871c..6ff43706d5 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/jobs/PushSendJob.java +++ b/app/src/main/java/org/thoughtcrime/securesms/jobs/PushSendJob.java @@ -446,17 +446,6 @@ public abstract class PushSendJob extends SendJob { } } - protected SignalServiceSyncMessage buildSelfSendSyncMessage(@NonNull Context context, @NonNull SignalServiceDataMessage message, Optional syncAccess) { - SignalServiceAddress localAddress = new SignalServiceAddress(Recipient.self().requireAci(), Recipient.self().requireE164()); - SentTranscriptMessage transcript = new SentTranscriptMessage(Optional.of(localAddress), - message.getTimestamp(), - message, - message.getExpiresInSeconds(), - Collections.singletonMap(localAddress, syncAccess.isPresent()), - false); - return SignalServiceSyncMessage.forSentTranscript(transcript); - } - protected void handleProofRequiredException(@NonNull ProofRequiredException proofRequired, @Nullable Recipient recipient, long threadId, long messageId, boolean isMms) throws ProofRequiredException, RetryLaterException { diff --git a/app/src/main/java/org/thoughtcrime/securesms/jobs/PushTextSendJob.java b/app/src/main/java/org/thoughtcrime/securesms/jobs/PushTextSendJob.java index 4bbbf79c09..fada00f4d2 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/jobs/PushTextSendJob.java +++ b/app/src/main/java/org/thoughtcrime/securesms/jobs/PushTextSendJob.java @@ -190,10 +190,9 @@ public class PushTextSendJob extends PushSendJob { if (Util.equals(SignalStore.account().getAci(), address.getAci())) { Optional syncAccess = UnidentifiedAccessUtil.getAccessForSync(context); - SignalServiceSyncMessage syncMessage = buildSelfSendSyncMessage(context, textSecureMessage, syncAccess); SignalLocalMetrics.IndividualMessageSend.onDeliveryStarted(messageId); - SendMessageResult result = messageSender.sendSyncMessage(syncMessage, syncAccess); + SendMessageResult result = messageSender.sendSyncMessage(textSecureMessage); SignalDatabase.messageLog().insertIfPossible(messageRecipient.getId(), message.getDateSent(), result, ContentHint.RESENDABLE, new MessageId(messageId, false)); return syncAccess.isPresent(); diff --git a/app/src/main/java/org/thoughtcrime/securesms/jobs/ReactionSendJob.java b/app/src/main/java/org/thoughtcrime/securesms/jobs/ReactionSendJob.java index 8a63f86c6c..2ce73edef0 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/jobs/ReactionSendJob.java +++ b/app/src/main/java/org/thoughtcrime/securesms/jobs/ReactionSendJob.java @@ -12,6 +12,7 @@ import org.thoughtcrime.securesms.database.SignalDatabase; import org.thoughtcrime.securesms.database.model.MessageId; import org.thoughtcrime.securesms.database.model.MessageRecord; import org.thoughtcrime.securesms.database.model.ReactionRecord; +import org.thoughtcrime.securesms.dependencies.ApplicationDependencies; import org.thoughtcrime.securesms.groups.GroupId; import org.thoughtcrime.securesms.jobmanager.Data; import org.thoughtcrime.securesms.jobmanager.Job; @@ -227,14 +228,20 @@ public class ReactionSendJob extends BaseJob { GroupUtil.setDataMessageGroupContext(context, dataMessageBuilder, conversationRecipient.requireGroupId().requirePush()); } - SignalServiceDataMessage dataMessage = dataMessageBuilder.build(); - List results = GroupSendUtil.sendResendableDataMessage(context, - conversationRecipient.getGroupId().transform(GroupId::requireV2).orNull(), - destinations, - false, - ContentHint.RESENDABLE, - messageId, - dataMessage); + SignalServiceDataMessage dataMessage = dataMessageBuilder.build(); + List nonSelfDestinations = destinations.stream().filter(r -> !r.isSelf()).collect(Collectors.toList()); + boolean includesSelf = nonSelfDestinations.size() != destinations.size(); + List results = GroupSendUtil.sendResendableDataMessage(context, + conversationRecipient.getGroupId().transform(GroupId::requireV2).orNull(), + nonSelfDestinations, + false, + ContentHint.RESENDABLE, + messageId, + dataMessage); + + if (includesSelf) { + results.add(ApplicationDependencies.getSignalServiceMessageSender().sendSyncMessage(dataMessage)); + } return GroupSendJobHelper.getCompletedSends(destinations, results); } diff --git a/app/src/main/java/org/thoughtcrime/securesms/jobs/SendDeliveryReceiptJob.java b/app/src/main/java/org/thoughtcrime/securesms/jobs/SendDeliveryReceiptJob.java index 12bae1ed0c..dfd4dff316 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/jobs/SendDeliveryReceiptJob.java +++ b/app/src/main/java/org/thoughtcrime/securesms/jobs/SendDeliveryReceiptJob.java @@ -102,6 +102,11 @@ public class SendDeliveryReceiptJob extends BaseJob { SignalServiceMessageSender messageSender = ApplicationDependencies.getSignalServiceMessageSender(); Recipient recipient = Recipient.resolved(recipientId); + if (recipient.isSelf()) { + Log.i(TAG, "Not sending to self, abort"); + return; + } + if (recipient.isUnregistered()) { Log.w(TAG, recipient.getId() + " is unregistered!"); return; diff --git a/app/src/main/java/org/thoughtcrime/securesms/jobs/SendReadReceiptJob.java b/app/src/main/java/org/thoughtcrime/securesms/jobs/SendReadReceiptJob.java index a89255eec6..9e1ed3fae9 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/jobs/SendReadReceiptJob.java +++ b/app/src/main/java/org/thoughtcrime/securesms/jobs/SendReadReceiptJob.java @@ -4,6 +4,7 @@ package org.thoughtcrime.securesms.jobs; import android.app.Application; import androidx.annotation.NonNull; +import androidx.annotation.VisibleForTesting; import org.signal.core.util.logging.Log; import org.thoughtcrime.securesms.crypto.UnidentifiedAccessUtil; @@ -59,6 +60,7 @@ public class SendReadReceiptJob extends BaseJob { private final long timestamp; private final List messageIds; + @VisibleForTesting public SendReadReceiptJob(long threadId, @NonNull RecipientId recipientId, List messageSentTimestamps, List messageIds) { this(new Job.Parameters.Builder() .addConstraint(NetworkConstraint.KEY) @@ -94,6 +96,10 @@ public class SendReadReceiptJob extends BaseJob { * maximum size. */ public static void enqueue(long threadId, @NonNull RecipientId recipientId, List markedMessageInfos) { + if (recipientId.equals(Recipient.self().getId())) { + return; + } + JobManager jobManager = ApplicationDependencies.getJobManager(); List> messageIdChunks = Util.chunk(markedMessageInfos, MAX_TIMESTAMPS); @@ -146,6 +152,10 @@ public class SendReadReceiptJob extends BaseJob { Recipient recipient = Recipient.resolved(recipientId); + if (recipient.isSelf()) { + Log.i(TAG, "Not sending to self, aborting."); + } + if (recipient.isBlocked()) { Log.w(TAG, "Refusing to send receipts to blocked recipient"); return; diff --git a/app/src/main/java/org/thoughtcrime/securesms/jobs/SendViewedReceiptJob.java b/app/src/main/java/org/thoughtcrime/securesms/jobs/SendViewedReceiptJob.java index f71eb41e44..b456edd33c 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/jobs/SendViewedReceiptJob.java +++ b/app/src/main/java/org/thoughtcrime/securesms/jobs/SendViewedReceiptJob.java @@ -150,6 +150,11 @@ public class SendViewedReceiptJob extends BaseJob { Recipient recipient = Recipient.resolved(recipientId); + if (recipient.isSelf()) { + Log.i(TAG, "Not sending view receipt to self."); + return; + } + if (recipient.isBlocked()) { Log.w(TAG, "Refusing to send receipts to blocked recipient"); return; diff --git a/app/src/test/java/org/thoughtcrime/securesms/notifications/MarkReadReceiverTest.java b/app/src/test/java/org/thoughtcrime/securesms/notifications/MarkReadReceiverTest.java index aef3eb6290..9f27785ea6 100644 --- a/app/src/test/java/org/thoughtcrime/securesms/notifications/MarkReadReceiverTest.java +++ b/app/src/test/java/org/thoughtcrime/securesms/notifications/MarkReadReceiverTest.java @@ -19,6 +19,7 @@ import org.thoughtcrime.securesms.jobmanager.Data; import org.thoughtcrime.securesms.jobmanager.Job; import org.thoughtcrime.securesms.jobmanager.JobManager; import org.thoughtcrime.securesms.jobs.MultiDeviceReadUpdateJob; +import org.thoughtcrime.securesms.recipients.Recipient; import org.thoughtcrime.securesms.recipients.RecipientId; import org.thoughtcrime.securesms.util.Util; import org.whispersystems.libsignal.util.Pair; @@ -37,21 +38,25 @@ import static org.powermock.api.mockito.PowerMockito.mockStatic; import static org.powermock.api.mockito.PowerMockito.when; @RunWith(PowerMockRunner.class) -@PrepareForTest(ApplicationDependencies.class) +@PrepareForTest({ApplicationDependencies.class, Recipient.class}) public class MarkReadReceiverTest { private final Context mockContext = mock(Context.class); private final JobManager mockJobManager = mock(JobManager.class); + private final Recipient mockSelf = mock(Recipient.class); private final List jobs = new LinkedList<>(); @Before public void setUp() { mockStatic(ApplicationDependencies.class); + mockStatic(Recipient.class); when(ApplicationDependencies.getJobManager()).thenReturn(mockJobManager); doAnswer((Answer) invocation -> { jobs.add((Job) invocation.getArguments()[0]); return null; }).when(mockJobManager).add(any()); + when(Recipient.self()).thenReturn(mockSelf); + when(mockSelf.getId()).thenReturn(RecipientId.from(-1)); } @Test diff --git a/libsignal/service/src/main/java/org/whispersystems/signalservice/api/SignalServiceMessageSender.java b/libsignal/service/src/main/java/org/whispersystems/signalservice/api/SignalServiceMessageSender.java index 9511d68ca0..7af84c5ae9 100644 --- a/libsignal/service/src/main/java/org/whispersystems/signalservice/api/SignalServiceMessageSender.java +++ b/libsignal/service/src/main/java/org/whispersystems/signalservice/api/SignalServiceMessageSender.java @@ -487,6 +487,12 @@ public class SignalServiceMessageSender { return results; } + public SendMessageResult sendSyncMessage(SignalServiceDataMessage dataMessage) + throws IOException, UntrustedIdentityException + { + return sendSyncMessage(createSelfSendSyncMessage(dataMessage), Optional.absent()); + } + public SendMessageResult sendSyncMessage(SignalServiceSyncMessage message, Optional unidentifiedAccess) throws IOException, UntrustedIdentityException { @@ -1537,6 +1543,16 @@ public class SignalServiceMessageSender { return results; } + private SignalServiceSyncMessage createSelfSendSyncMessage(SignalServiceDataMessage message) { + SentTranscriptMessage transcript = new SentTranscriptMessage(Optional.of(localAddress), + message.getTimestamp(), + message, + message.getExpiresInSeconds(), + Collections.singletonMap(localAddress, false), + false); + return SignalServiceSyncMessage.forSentTranscript(transcript); + } + private List sendMessage(List recipients, List> unidentifiedAccess, long timestamp,