use of org.thoughtcrime.securesms.database.model.MessageId in project Signal-Android by signalapp.
the class MessageSender method sendLocalMediaSelf.
private static void sendLocalMediaSelf(Context context, long messageId) {
try {
ExpiringMessageManager expirationManager = ApplicationDependencies.getExpiringMessageManager();
MessageDatabase mmsDatabase = SignalDatabase.mms();
MmsSmsDatabase mmsSmsDatabase = SignalDatabase.mmsSms();
OutgoingMediaMessage message = mmsDatabase.getOutgoingMessage(messageId);
SyncMessageId syncId = new SyncMessageId(Recipient.self().getId(), message.getSentTimeMillis());
List<Attachment> attachments = new LinkedList<>();
attachments.addAll(message.getAttachments());
attachments.addAll(Stream.of(message.getLinkPreviews()).map(LinkPreview::getThumbnail).filter(Optional::isPresent).map(Optional::get).toList());
attachments.addAll(Stream.of(message.getSharedContacts()).map(Contact::getAvatar).withoutNulls().map(Contact.Avatar::getAttachment).withoutNulls().toList());
List<AttachmentCompressionJob> compressionJobs = Stream.of(attachments).map(a -> AttachmentCompressionJob.fromAttachment((DatabaseAttachment) a, false, -1)).toList();
List<AttachmentMarkUploadedJob> fakeUploadJobs = Stream.of(attachments).map(a -> new AttachmentMarkUploadedJob(messageId, ((DatabaseAttachment) a).getAttachmentId())).toList();
ApplicationDependencies.getJobManager().startChain(compressionJobs).then(fakeUploadJobs).enqueue();
mmsDatabase.markAsSent(messageId, true);
mmsDatabase.markUnidentified(messageId, true);
mmsSmsDatabase.incrementDeliveryReceiptCount(syncId, System.currentTimeMillis());
mmsSmsDatabase.incrementReadReceiptCount(syncId, System.currentTimeMillis());
mmsSmsDatabase.incrementViewedReceiptCount(syncId, System.currentTimeMillis());
if (message.getExpiresIn() > 0 && !message.isExpirationUpdate()) {
mmsDatabase.markExpireStarted(messageId);
expirationManager.scheduleDeletion(messageId, true, message.getExpiresIn());
}
} catch (NoSuchMessageException | MmsException e) {
Log.w(TAG, "Failed to update self-sent message.", e);
}
}
use of org.thoughtcrime.securesms.database.model.MessageId in project Signal-Android by signalapp.
the class MessageContentProcessor method updateGroupReceiptStatus.
private void updateGroupReceiptStatus(@NonNull SentTranscriptMessage message, long messageId, @NonNull GroupId groupString) {
GroupReceiptDatabase receiptDatabase = SignalDatabase.groupReceipts();
List<RecipientId> messageRecipientIds = Stream.of(message.getRecipients()).map(RecipientId::from).toList();
List<Recipient> members = SignalDatabase.groups().getGroupMembers(groupString, GroupDatabase.MemberSet.FULL_MEMBERS_EXCLUDING_SELF);
Map<RecipientId, Integer> localReceipts = Stream.of(receiptDatabase.getGroupReceiptInfo(messageId)).collect(Collectors.toMap(GroupReceiptInfo::getRecipientId, GroupReceiptInfo::getStatus));
for (RecipientId messageRecipientId : messageRecipientIds) {
// noinspection ConstantConditions
if (localReceipts.containsKey(messageRecipientId) && localReceipts.get(messageRecipientId) < GroupReceiptDatabase.STATUS_UNDELIVERED) {
receiptDatabase.update(messageRecipientId, messageId, GroupReceiptDatabase.STATUS_UNDELIVERED, message.getTimestamp());
} else if (!localReceipts.containsKey(messageRecipientId)) {
receiptDatabase.insert(Collections.singletonList(messageRecipientId), messageId, GroupReceiptDatabase.STATUS_UNDELIVERED, message.getTimestamp());
}
}
List<org.whispersystems.libsignal.util.Pair<RecipientId, Boolean>> unidentifiedStatus = Stream.of(members).map(m -> new org.whispersystems.libsignal.util.Pair<>(m.getId(), message.isUnidentified(m.requireServiceId().toString()))).toList();
receiptDatabase.setUnidentified(unidentifiedStatus, messageId);
}
use of org.thoughtcrime.securesms.database.model.MessageId in project Signal-Android by signalapp.
the class MessageContentProcessor method handleExpirationUpdate.
@Nullable
private MessageId handleExpirationUpdate(@NonNull SignalServiceContent content, @NonNull SignalServiceDataMessage message, @NonNull Optional<Long> smsMessageId, @NonNull Optional<GroupId> groupId, @NonNull Recipient senderRecipient, @NonNull Recipient threadRecipient, long receivedTime) throws StorageFailedException {
log(content.getTimestamp(), "Expiration update.");
if (groupId.isPresent() && groupId.get().isV2()) {
warn(String.valueOf(content.getTimestamp()), "Expiration update received for GV2. Ignoring.");
return null;
}
int expiresInSeconds = message.getExpiresInSeconds();
Optional<SignalServiceGroupContext> groupContext = message.getGroupContext();
if (threadRecipient.getExpiresInSeconds() == expiresInSeconds) {
log(String.valueOf(content.getTimestamp()), "No change in message expiry for group. Ignoring.");
return null;
}
try {
MessageDatabase database = SignalDatabase.mms();
IncomingMediaMessage mediaMessage = new IncomingMediaMessage(senderRecipient.getId(), content.getTimestamp(), content.getServerReceivedTimestamp(), receivedTime, -1, expiresInSeconds * 1000L, true, false, content.isNeedsReceipt(), Optional.absent(), groupContext, Optional.absent(), Optional.absent(), Optional.absent(), Optional.absent(), Optional.absent(), Optional.absent(), content.getServerUuid());
Optional<InsertResult> insertResult = database.insertSecureDecryptedMessageInbox(mediaMessage, -1);
SignalDatabase.recipients().setExpireMessages(threadRecipient.getId(), expiresInSeconds);
if (smsMessageId.isPresent()) {
SignalDatabase.sms().deleteMessage(smsMessageId.get());
}
if (insertResult.isPresent()) {
return new MessageId(insertResult.get().getMessageId(), true);
}
} catch (MmsException e) {
throw new StorageFailedException(e, content.getSender().getIdentifier(), content.getSenderDevice());
}
return null;
}
use of org.thoughtcrime.securesms.database.model.MessageId in project Signal-Android by signalapp.
the class MessageContentProcessor method handleReaction.
@Nullable
private MessageId handleReaction(@NonNull SignalServiceContent content, @NonNull SignalServiceDataMessage message, @NonNull Recipient senderRecipient) {
log(content.getTimestamp(), "Handle reaction for message " + message.getReaction().get().getTargetSentTimestamp());
SignalServiceDataMessage.Reaction reaction = message.getReaction().get();
if (!EmojiUtil.isEmoji(reaction.getEmoji())) {
Log.w(TAG, "Reaction text is not a valid emoji! Ignoring the message.");
return null;
}
Recipient targetAuthor = Recipient.externalPush(reaction.getTargetAuthor());
MessageRecord targetMessage = SignalDatabase.mmsSms().getMessageFor(reaction.getTargetSentTimestamp(), targetAuthor.getId());
if (targetMessage == null) {
warn(String.valueOf(content.getTimestamp()), "[handleReaction] Could not find matching message! Putting it in the early message cache. timestamp: " + reaction.getTargetSentTimestamp() + " author: " + targetAuthor.getId());
ApplicationDependencies.getEarlyMessageCache().store(targetAuthor.getId(), reaction.getTargetSentTimestamp(), content);
return null;
}
if (targetMessage.isRemoteDelete()) {
warn(String.valueOf(content.getTimestamp()), "[handleReaction] Found a matching message, but it's flagged as remotely deleted. timestamp: " + reaction.getTargetSentTimestamp() + " author: " + targetAuthor.getId());
return null;
}
ThreadRecord targetThread = SignalDatabase.threads().getThreadRecord(targetMessage.getThreadId());
if (targetThread == null) {
warn(String.valueOf(content.getTimestamp()), "[handleReaction] Could not find a thread for the message! timestamp: " + reaction.getTargetSentTimestamp() + " author: " + targetAuthor.getId());
return null;
}
Recipient threadRecipient = targetThread.getRecipient().resolve();
if (threadRecipient.isGroup() && !threadRecipient.getParticipants().contains(senderRecipient)) {
warn(String.valueOf(content.getTimestamp()), "[handleReaction] Reaction author is not in the group! timestamp: " + reaction.getTargetSentTimestamp() + " author: " + targetAuthor.getId());
return null;
}
if (!threadRecipient.isGroup() && !senderRecipient.equals(threadRecipient) && !senderRecipient.isSelf()) {
warn(String.valueOf(content.getTimestamp()), "[handleReaction] Reaction author is not a part of the 1:1 thread! timestamp: " + reaction.getTargetSentTimestamp() + " author: " + targetAuthor.getId());
return null;
}
MessageId targetMessageId = new MessageId(targetMessage.getId(), targetMessage.isMms());
if (reaction.isRemove()) {
SignalDatabase.reactions().deleteReaction(targetMessageId, senderRecipient.getId());
ApplicationDependencies.getMessageNotifier().updateNotification(context);
} else {
ReactionRecord reactionRecord = new ReactionRecord(reaction.getEmoji(), senderRecipient.getId(), message.getTimestamp(), System.currentTimeMillis());
SignalDatabase.reactions().addReaction(targetMessageId, reactionRecord);
ApplicationDependencies.getMessageNotifier().updateNotification(context, targetMessage.getThreadId(), false);
}
return new MessageId(targetMessage.getId(), targetMessage.isMms());
}
use of org.thoughtcrime.securesms.database.model.MessageId in project Signal-Android by signalapp.
the class MessageContentProcessor method handleRemoteDelete.
@Nullable
private MessageId handleRemoteDelete(@NonNull SignalServiceContent content, @NonNull SignalServiceDataMessage message, @NonNull Recipient senderRecipient) {
log(content.getTimestamp(), "Remote delete for message " + message.getRemoteDelete().get().getTargetSentTimestamp());
SignalServiceDataMessage.RemoteDelete delete = message.getRemoteDelete().get();
MessageRecord targetMessage = SignalDatabase.mmsSms().getMessageFor(delete.getTargetSentTimestamp(), senderRecipient.getId());
if (targetMessage != null && RemoteDeleteUtil.isValidReceive(targetMessage, senderRecipient, content.getServerReceivedTimestamp())) {
MessageDatabase db = targetMessage.isMms() ? SignalDatabase.mms() : SignalDatabase.sms();
db.markAsRemoteDelete(targetMessage.getId());
ApplicationDependencies.getMessageNotifier().updateNotification(context, targetMessage.getThreadId(), false);
return new MessageId(targetMessage.getId(), targetMessage.isMms());
} else if (targetMessage == null) {
warn(String.valueOf(content.getTimestamp()), "[handleRemoteDelete] Could not find matching message! timestamp: " + delete.getTargetSentTimestamp() + " author: " + senderRecipient.getId());
ApplicationDependencies.getEarlyMessageCache().store(senderRecipient.getId(), delete.getTargetSentTimestamp(), content);
return null;
} else {
warn(String.valueOf(content.getTimestamp()), String.format(Locale.ENGLISH, "[handleRemoteDelete] Invalid remote delete! deleteTime: %d, targetTime: %d, deleteAuthor: %s, targetAuthor: %s", content.getServerReceivedTimestamp(), targetMessage.getServerTimestamp(), senderRecipient.getId(), targetMessage.getRecipient().getId()));
return null;
}
}
Aggregations