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 e4af6c43f3c94ed611e12b14d155f89d5c5e161a..ee062da34f9450d28377165fa0a53a23db6224ef 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<UnidentifiedAccessPair> syncAccess = UnidentifiedAccessUtil.getAccessForSync(context); - SignalServiceSyncMessage syncMessage = buildSelfSendSyncMessage(context, mediaMessage, syncAccess); - - SendMessageResult result = messageSender.sendSyncMessage(syncMessage, syncAccess); + Optional<UnidentifiedAccessPair> 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 790399871c390d2e929fe65c53777747642902b6..6ff43706d522a93cdfc822366fa3143155a29d66 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<UnidentifiedAccessPair> 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 4bbbf79c09a6bd8e5ee9008050b775666dc7e7fe..fada00f4d2cc10c9d06b759333473f6baf657234 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<UnidentifiedAccessPair> 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 8a63f86c6c56f026c01e321592cf8b6d8ec5059c..2ce73edef04166f7d6ead74f012e67a432772052 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<SendMessageResult> results = GroupSendUtil.sendResendableDataMessage(context, - conversationRecipient.getGroupId().transform(GroupId::requireV2).orNull(), - destinations, - false, - ContentHint.RESENDABLE, - messageId, - dataMessage); + SignalServiceDataMessage dataMessage = dataMessageBuilder.build(); + List<Recipient> nonSelfDestinations = destinations.stream().filter(r -> !r.isSelf()).collect(Collectors.toList()); + boolean includesSelf = nonSelfDestinations.size() != destinations.size(); + List<SendMessageResult> 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 12bae1ed0c5d8ad2b8467a338e469c210bd6ae7b..dfd4dff3165d2822ceeea8cb97d7e334490ca512 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 a89255eec620a2ed8f949b07da81543fa24f01c3..9e1ed3fae993d0b05b6e7ea2088e8363072a0001 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<MessageId> messageIds; + @VisibleForTesting public SendReadReceiptJob(long threadId, @NonNull RecipientId recipientId, List<Long> messageSentTimestamps, List<MessageId> 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<MarkedMessageInfo> markedMessageInfos) { + if (recipientId.equals(Recipient.self().getId())) { + return; + } + JobManager jobManager = ApplicationDependencies.getJobManager(); List<List<MarkedMessageInfo>> 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 f71eb41e44c752acff70f356d33ad03e9556f8f8..b456edd33c93919499e3afafa98d7915bbb8d68b 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 aef3eb6290fd45cb695bf08abdf4a866b356680a..9f27785ea645174e4c549bef9382d6d121a89f07 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<Job> jobs = new LinkedList<>(); @Before public void setUp() { mockStatic(ApplicationDependencies.class); + mockStatic(Recipient.class); when(ApplicationDependencies.getJobManager()).thenReturn(mockJobManager); doAnswer((Answer<Void>) 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 09eda89e4790ea84daa42a6d6c6f7f5d1b759810..ecee829154d58fee49fcde1cc992bc67b0defbe3 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<UnidentifiedAccessPair> unidentifiedAccess) throws IOException, UntrustedIdentityException { @@ -1528,6 +1534,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<SendMessageResult> sendMessage(List<SignalServiceAddress> recipients, List<Optional<UnidentifiedAccess>> unidentifiedAccess, long timestamp,