Search in sources :

Example 86 with MessageId

use of org.thoughtcrime.securesms.database.model.MessageId in project Signal-Android by signalapp.

the class ConversationParentFragment method onReactionSelected.

@Override
public void onReactionSelected(MessageRecord messageRecord, String emoji) {
    final Context context = requireContext().getApplicationContext();
    reactionDelegate.hide();
    SignalExecutors.BOUNDED.execute(() -> {
        ReactionRecord oldRecord = Stream.of(messageRecord.getReactions()).filter(record -> record.getAuthor().equals(Recipient.self().getId())).findFirst().orElse(null);
        if (oldRecord != null && oldRecord.getEmoji().equals(emoji)) {
            MessageSender.sendReactionRemoval(context, new MessageId(messageRecord.getId(), messageRecord.isMms()), oldRecord);
        } else {
            MessageSender.sendNewReaction(context, new MessageId(messageRecord.getId(), messageRecord.isMms()), emoji);
        }
    });
}
Also used : Context(android.content.Context) ReactionRecord(org.thoughtcrime.securesms.database.model.ReactionRecord) MessageId(org.thoughtcrime.securesms.database.model.MessageId)

Example 87 with MessageId

use of org.thoughtcrime.securesms.database.model.MessageId in project Signal-Android by signalapp.

the class RemoteDeleteSendJob method deliver.

@NonNull
private List<Recipient> deliver(@NonNull Recipient conversationRecipient, @NonNull List<Recipient> destinations, long targetSentTimestamp) throws IOException, UntrustedIdentityException {
    SignalServiceDataMessage.Builder dataMessageBuilder = SignalServiceDataMessage.newBuilder().withTimestamp(System.currentTimeMillis()).withRemoteDelete(new SignalServiceDataMessage.RemoteDelete(targetSentTimestamp));
    if (conversationRecipient.isGroup()) {
        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, new MessageId(messageId, isMms), dataMessage);
    return GroupSendJobHelper.getCompletedSends(destinations, results);
}
Also used : SignalServiceDataMessage(org.whispersystems.signalservice.api.messages.SignalServiceDataMessage) SendMessageResult(org.whispersystems.signalservice.api.messages.SendMessageResult) GroupId(org.thoughtcrime.securesms.groups.GroupId) MessageId(org.thoughtcrime.securesms.database.model.MessageId) NonNull(androidx.annotation.NonNull)

Example 88 with MessageId

use of org.thoughtcrime.securesms.database.model.MessageId in project Signal-Android by signalapp.

the class SendReadReceiptJob method enqueue.

/**
 * Enqueues all the necessary jobs for read receipts, ensuring that they're all within the
 * 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);
    if (messageIdChunks.size() > 1) {
        Log.w(TAG, "Large receipt count! Had to break into multiple chunks. Total count: " + markedMessageInfos.size());
    }
    for (List<MarkedMessageInfo> chunk : messageIdChunks) {
        List<Long> sentTimestamps = chunk.stream().map(info -> info.getSyncMessageId().getTimetamp()).collect(Collectors.toList());
        List<MessageId> messageIds = chunk.stream().map(MarkedMessageInfo::getMessageId).collect(Collectors.toList());
        jobManager.add(new SendReadReceiptJob(threadId, recipientId, sentTimestamps, messageIds));
    }
}
Also used : MarkedMessageInfo(org.thoughtcrime.securesms.database.MessageDatabase.MarkedMessageInfo) ServerRejectedException(org.whispersystems.signalservice.api.push.exceptions.ServerRejectedException) SignalDatabase(org.thoughtcrime.securesms.database.SignalDatabase) ContentHint(org.whispersystems.signalservice.api.crypto.ContentHint) Util(org.thoughtcrime.securesms.util.Util) SendMessageResult(org.whispersystems.signalservice.api.messages.SendMessageResult) NonNull(androidx.annotation.NonNull) Data(org.thoughtcrime.securesms.jobmanager.Data) JobManager(org.thoughtcrime.securesms.jobmanager.JobManager) RecipientUtil(org.thoughtcrime.securesms.recipients.RecipientUtil) NotPushRegisteredException(org.thoughtcrime.securesms.net.NotPushRegisteredException) SignalServiceAddress(org.whispersystems.signalservice.api.push.SignalServiceAddress) ArrayList(java.util.ArrayList) TextSecurePreferences(org.thoughtcrime.securesms.util.TextSecurePreferences) RecipientId(org.thoughtcrime.securesms.recipients.RecipientId) Recipient(org.thoughtcrime.securesms.recipients.Recipient) SignalServiceMessageSender(org.whispersystems.signalservice.api.SignalServiceMessageSender) MessageId(org.thoughtcrime.securesms.database.model.MessageId) PushNetworkException(org.whispersystems.signalservice.api.push.exceptions.PushNetworkException) ApplicationDependencies(org.thoughtcrime.securesms.dependencies.ApplicationDependencies) NetworkConstraint(org.thoughtcrime.securesms.jobmanager.impl.NetworkConstraint) IOException(java.io.IOException) UnidentifiedAccessUtil(org.thoughtcrime.securesms.crypto.UnidentifiedAccessUtil) UndeliverableMessageException(org.thoughtcrime.securesms.transport.UndeliverableMessageException) Collectors(java.util.stream.Collectors) TimeUnit(java.util.concurrent.TimeUnit) Log(org.signal.core.util.logging.Log) List(java.util.List) UntrustedIdentityException(org.whispersystems.signalservice.api.crypto.UntrustedIdentityException) Application(android.app.Application) Job(org.thoughtcrime.securesms.jobmanager.Job) SignalServiceReceiptMessage(org.whispersystems.signalservice.api.messages.SignalServiceReceiptMessage) VisibleForTesting(androidx.annotation.VisibleForTesting) Collections(java.util.Collections) ArrayList(java.util.ArrayList) List(java.util.List) JobManager(org.thoughtcrime.securesms.jobmanager.JobManager) MarkedMessageInfo(org.thoughtcrime.securesms.database.MessageDatabase.MarkedMessageInfo) MessageId(org.thoughtcrime.securesms.database.model.MessageId)

Example 89 with MessageId

use of org.thoughtcrime.securesms.database.model.MessageId in project Signal-Android by signalapp.

the class PushGroupSendJob method deliver.

private List<SendMessageResult> deliver(OutgoingMediaMessage message, @NonNull Recipient groupRecipient, @NonNull List<Recipient> destinations) throws IOException, UntrustedIdentityException, UndeliverableMessageException {
    try {
        rotateSenderCertificateIfNecessary();
        GroupId.Push groupId = groupRecipient.requireGroupId().requirePush();
        Optional<byte[]> profileKey = getProfileKey(groupRecipient);
        Optional<Quote> quote = getQuoteFor(message);
        Optional<SignalServiceDataMessage.Sticker> sticker = getStickerFor(message);
        List<SharedContact> sharedContacts = getSharedContactsFor(message);
        List<Preview> previews = getPreviewsFor(message);
        List<SignalServiceDataMessage.Mention> mentions = getMentionsFor(message.getMentions());
        List<Attachment> attachments = Stream.of(message.getAttachments()).filterNot(Attachment::isSticker).toList();
        List<SignalServiceAttachment> attachmentPointers = getAttachmentPointersFor(attachments);
        boolean isRecipientUpdate = Stream.of(SignalDatabase.groupReceipts().getGroupReceiptInfo(messageId)).anyMatch(info -> info.getStatus() > GroupReceiptDatabase.STATUS_UNDELIVERED);
        if (message.isGroup()) {
            OutgoingGroupUpdateMessage groupMessage = (OutgoingGroupUpdateMessage) message;
            if (groupMessage.isV2Group()) {
                MessageGroupContext.GroupV2Properties properties = groupMessage.requireGroupV2Properties();
                GroupContextV2 groupContext = properties.getGroupContext();
                SignalServiceGroupV2.Builder builder = SignalServiceGroupV2.newBuilder(properties.getGroupMasterKey()).withRevision(groupContext.getRevision());
                ByteString groupChange = groupContext.getGroupChange();
                if (groupChange != null) {
                    builder.withSignedGroupChange(groupChange.toByteArray());
                }
                SignalServiceGroupV2 group = builder.build();
                SignalServiceDataMessage groupDataMessage = SignalServiceDataMessage.newBuilder().withTimestamp(message.getSentTimeMillis()).withExpiration(groupRecipient.getExpiresInSeconds()).asGroupMessage(group).build();
                return GroupSendUtil.sendResendableDataMessage(context, groupRecipient.requireGroupId().requireV2(), destinations, isRecipientUpdate, ContentHint.IMPLICIT, new MessageId(messageId, true), groupDataMessage);
            } else {
                throw new UndeliverableMessageException("Messages can no longer be sent to V1 groups!");
            }
        } else {
            Optional<GroupDatabase.GroupRecord> groupRecord = SignalDatabase.groups().getGroup(groupRecipient.requireGroupId());
            if (groupRecord.isPresent() && groupRecord.get().isAnnouncementGroup() && !groupRecord.get().isAdmin(Recipient.self())) {
                throw new UndeliverableMessageException("Non-admins cannot send messages in announcement groups!");
            }
            SignalServiceDataMessage.Builder builder = SignalServiceDataMessage.newBuilder().withTimestamp(message.getSentTimeMillis());
            GroupUtil.setDataMessageGroupContext(context, builder, groupId);
            SignalServiceDataMessage groupMessage = builder.withAttachments(attachmentPointers).withBody(message.getBody()).withExpiration((int) (message.getExpiresIn() / 1000)).withViewOnce(message.isViewOnce()).asExpirationUpdate(message.isExpirationUpdate()).withProfileKey(profileKey.orNull()).withQuote(quote.orNull()).withSticker(sticker.orNull()).withSharedContacts(sharedContacts).withPreviews(previews).withMentions(mentions).build();
            Log.i(TAG, JobLogger.format(this, "Beginning message send."));
            return GroupSendUtil.sendResendableDataMessage(context, groupRecipient.getGroupId().transform(GroupId::requireV2).orNull(), destinations, isRecipientUpdate, ContentHint.RESENDABLE, new MessageId(messageId, true), groupMessage);
        }
    } catch (ServerRejectedException e) {
        throw new UndeliverableMessageException(e);
    }
}
Also used : ByteString(com.google.protobuf.ByteString) SignalServiceAttachment(org.whispersystems.signalservice.api.messages.SignalServiceAttachment) Attachment(org.thoughtcrime.securesms.attachments.Attachment) OutgoingGroupUpdateMessage(org.thoughtcrime.securesms.mms.OutgoingGroupUpdateMessage) GroupContextV2(org.whispersystems.signalservice.internal.push.SignalServiceProtos.GroupContextV2) MessageGroupContext(org.thoughtcrime.securesms.mms.MessageGroupContext) UndeliverableMessageException(org.thoughtcrime.securesms.transport.UndeliverableMessageException) Preview(org.whispersystems.signalservice.api.messages.SignalServiceDataMessage.Preview) ServerRejectedException(org.whispersystems.signalservice.api.push.exceptions.ServerRejectedException) SignalServiceGroupV2(org.whispersystems.signalservice.api.messages.SignalServiceGroupV2) GroupId(org.thoughtcrime.securesms.groups.GroupId) Quote(org.whispersystems.signalservice.api.messages.SignalServiceDataMessage.Quote) SignalServiceAttachment(org.whispersystems.signalservice.api.messages.SignalServiceAttachment) SignalServiceDataMessage(org.whispersystems.signalservice.api.messages.SignalServiceDataMessage) SharedContact(org.whispersystems.signalservice.api.messages.shared.SharedContact) MessageId(org.thoughtcrime.securesms.database.model.MessageId)

Example 90 with MessageId

use of org.thoughtcrime.securesms.database.model.MessageId in project Signal-Android by signalapp.

the class PushMediaSendJob method deliver.

private boolean deliver(OutgoingMediaMessage message) throws IOException, InsecureFallbackApprovalException, UntrustedIdentityException, UndeliverableMessageException {
    if (message.getRecipient() == null) {
        throw new UndeliverableMessageException("No destination address.");
    }
    try {
        rotateSenderCertificateIfNecessary();
        Recipient messageRecipient = message.getRecipient().fresh();
        if (messageRecipient.isUnregistered()) {
            throw new UndeliverableMessageException(messageRecipient.getId() + " not registered!");
        }
        SignalServiceMessageSender messageSender = ApplicationDependencies.getSignalServiceMessageSender();
        SignalServiceAddress address = RecipientUtil.toSignalServiceAddress(context, messageRecipient);
        List<Attachment> attachments = Stream.of(message.getAttachments()).filterNot(Attachment::isSticker).toList();
        List<SignalServiceAttachment> serviceAttachments = getAttachmentPointersFor(attachments);
        Optional<byte[]> profileKey = getProfileKey(messageRecipient);
        Optional<SignalServiceDataMessage.Quote> quote = getQuoteFor(message);
        Optional<SignalServiceDataMessage.Sticker> sticker = getStickerFor(message);
        List<SharedContact> sharedContacts = getSharedContactsFor(message);
        List<Preview> previews = getPreviewsFor(message);
        SignalServiceDataMessage mediaMessage = SignalServiceDataMessage.newBuilder().withBody(message.getBody()).withAttachments(serviceAttachments).withTimestamp(message.getSentTimeMillis()).withExpiration((int) (message.getExpiresIn() / 1000)).withViewOnce(message.isViewOnce()).withProfileKey(profileKey.orNull()).withQuote(quote.orNull()).withSticker(sticker.orNull()).withSharedContacts(sharedContacts).withPreviews(previews).asExpirationUpdate(message.isExpirationUpdate()).build();
        if (Util.equals(SignalStore.account().getAci(), address.getServiceId())) {
            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 {
            SendMessageResult result = messageSender.sendDataMessage(address, UnidentifiedAccessUtil.getAccessFor(context, messageRecipient), ContentHint.RESENDABLE, mediaMessage, IndividualSendEvents.EMPTY);
            SignalDatabase.messageLog().insertIfPossible(messageRecipient.getId(), message.getSentTimeMillis(), result, ContentHint.RESENDABLE, new MessageId(messageId, true));
            return result.getSuccess().isUnidentified();
        }
    } catch (UnregisteredUserException e) {
        warn(TAG, String.valueOf(message.getSentTimeMillis()), e);
        throw new InsecureFallbackApprovalException(e);
    } catch (FileNotFoundException e) {
        warn(TAG, String.valueOf(message.getSentTimeMillis()), e);
        throw new UndeliverableMessageException(e);
    } catch (ServerRejectedException e) {
        throw new UndeliverableMessageException(e);
    }
}
Also used : UnregisteredUserException(org.whispersystems.signalservice.api.push.exceptions.UnregisteredUserException) FileNotFoundException(java.io.FileNotFoundException) SignalServiceMessageSender(org.whispersystems.signalservice.api.SignalServiceMessageSender) SignalServiceAttachment(org.whispersystems.signalservice.api.messages.SignalServiceAttachment) Attachment(org.thoughtcrime.securesms.attachments.Attachment) InsecureFallbackApprovalException(org.thoughtcrime.securesms.transport.InsecureFallbackApprovalException) UndeliverableMessageException(org.thoughtcrime.securesms.transport.UndeliverableMessageException) SignalServiceAddress(org.whispersystems.signalservice.api.push.SignalServiceAddress) Preview(org.whispersystems.signalservice.api.messages.SignalServiceDataMessage.Preview) Recipient(org.thoughtcrime.securesms.recipients.Recipient) UnidentifiedAccessPair(org.whispersystems.signalservice.api.crypto.UnidentifiedAccessPair) ServerRejectedException(org.whispersystems.signalservice.api.push.exceptions.ServerRejectedException) SendMessageResult(org.whispersystems.signalservice.api.messages.SendMessageResult) SignalServiceAttachment(org.whispersystems.signalservice.api.messages.SignalServiceAttachment) SignalServiceDataMessage(org.whispersystems.signalservice.api.messages.SignalServiceDataMessage) SharedContact(org.whispersystems.signalservice.api.messages.shared.SharedContact) MessageId(org.thoughtcrime.securesms.database.model.MessageId) SyncMessageId(org.thoughtcrime.securesms.database.MessageDatabase.SyncMessageId)

Aggregations

MessageId (org.thoughtcrime.securesms.database.model.MessageId)90 RecipientId (org.thoughtcrime.securesms.recipients.RecipientId)40 NonNull (androidx.annotation.NonNull)30 Recipient (org.thoughtcrime.securesms.recipients.Recipient)30 Nullable (androidx.annotation.Nullable)28 LinkedList (java.util.LinkedList)24 List (java.util.List)24 SyncMessageId (org.thoughtcrime.securesms.database.MessageDatabase.SyncMessageId)24 Context (android.content.Context)22 IOException (java.io.IOException)22 Log (org.signal.core.util.logging.Log)22 ApplicationDependencies (org.thoughtcrime.securesms.dependencies.ApplicationDependencies)22 SignalServiceDataMessage (org.whispersystems.signalservice.api.messages.SignalServiceDataMessage)22 ContentValues (android.content.ContentValues)20 Collections (java.util.Collections)20 Attachment (org.thoughtcrime.securesms.attachments.Attachment)20 MessageDatabase (org.thoughtcrime.securesms.database.MessageDatabase)20 Cursor (android.database.Cursor)18 ArrayList (java.util.ArrayList)18 TextSecurePreferences (org.thoughtcrime.securesms.util.TextSecurePreferences)18