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);
}
});
}
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);
}
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));
}
}
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);
}
}
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);
}
}
Aggregations