use of org.whispersystems.signalservice.api.messages.SignalServiceDataMessage in project Signal-Android by WhisperSystems.
the class PaymentNotificationSendJob method onRun.
@Override
protected void onRun() throws Exception {
if (!Recipient.self().isRegistered()) {
throw new NotPushRegisteredException();
}
PaymentDatabase paymentDatabase = SignalDatabase.payments();
Recipient recipient = Recipient.resolved(recipientId);
if (recipient.isUnregistered()) {
Log.w(TAG, recipientId + " not registered!");
return;
}
SignalServiceMessageSender messageSender = ApplicationDependencies.getSignalServiceMessageSender();
SignalServiceAddress address = RecipientUtil.toSignalServiceAddress(context, recipient);
Optional<UnidentifiedAccessPair> unidentifiedAccess = UnidentifiedAccessUtil.getAccessFor(context, recipient);
PaymentDatabase.PaymentTransaction payment = paymentDatabase.getPayment(uuid);
if (payment == null) {
Log.w(TAG, "Could not find payment, cannot send notification " + uuid);
return;
}
if (payment.getReceipt() == null) {
Log.w(TAG, "Could not find payment receipt, cannot send notification " + uuid);
return;
}
SignalServiceDataMessage dataMessage = SignalServiceDataMessage.newBuilder().withPayment(new SignalServiceDataMessage.Payment(new SignalServiceDataMessage.PaymentNotification(payment.getReceipt(), payment.getNote()))).build();
SendMessageResult sendMessageResult = messageSender.sendDataMessage(address, unidentifiedAccess, ContentHint.DEFAULT, dataMessage, IndividualSendEvents.EMPTY);
if (sendMessageResult.getIdentityFailure() != null) {
Log.w(TAG, "Identity failure for " + recipient.getId());
} else if (sendMessageResult.isUnregisteredFailure()) {
Log.w(TAG, "Unregistered failure for " + recipient.getId());
} else if (sendMessageResult.getSuccess() == null) {
throw new RetryLaterException();
} else {
Log.i(TAG, String.format("Payment notification sent to %s for %s", recipientId, uuid));
}
}
use of org.whispersystems.signalservice.api.messages.SignalServiceDataMessage in project Signal-Android by WhisperSystems.
the class MessageContentProcessor method handlePayment.
private void handlePayment(@NonNull SignalServiceContent content, @NonNull SignalServiceDataMessage message, @NonNull Recipient senderRecipient) {
log(content.getTimestamp(), "Payment message.");
if (!message.getPayment().isPresent()) {
throw new AssertionError();
}
if (!message.getPayment().get().getPaymentNotification().isPresent()) {
warn(content.getTimestamp(), "Ignoring payment message without notification");
return;
}
SignalServiceDataMessage.PaymentNotification paymentNotification = message.getPayment().get().getPaymentNotification().get();
PaymentDatabase paymentDatabase = SignalDatabase.payments();
UUID uuid = UUID.randomUUID();
String queue = "Payment_" + PushProcessMessageJob.getQueueName(senderRecipient.getId());
try {
paymentDatabase.createIncomingPayment(uuid, senderRecipient.getId(), message.getTimestamp(), paymentNotification.getNote(), Money.MobileCoin.ZERO, Money.MobileCoin.ZERO, paymentNotification.getReceipt());
} catch (PaymentDatabase.PublicKeyConflictException e) {
warn(content.getTimestamp(), "Ignoring payment with public key already in database");
return;
} catch (SerializationException e) {
warn(content.getTimestamp(), "Ignoring payment with bad data.", e);
}
ApplicationDependencies.getJobManager().startChain(new PaymentTransactionCheckJob(uuid, queue)).then(PaymentLedgerUpdateJob.updateLedger()).enqueue();
}
use of org.whispersystems.signalservice.api.messages.SignalServiceDataMessage in project Signal-Android by WhisperSystems.
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.whispersystems.signalservice.api.messages.SignalServiceDataMessage in project Signal-Android by WhisperSystems.
the class MessageContentProcessor method shouldIgnore.
private boolean shouldIgnore(@NonNull SignalServiceContent content, @NonNull Recipient sender, @NonNull Recipient conversation) throws BadGroupIdException {
if (content.getDataMessage().isPresent()) {
SignalServiceDataMessage message = content.getDataMessage().get();
if (conversation.isGroup() && conversation.isBlocked()) {
return true;
} else if (conversation.isGroup()) {
GroupDatabase groupDatabase = SignalDatabase.groups();
Optional<GroupId> groupId = GroupUtil.idFromGroupContext(message.getGroupContext());
if (groupId.isPresent() && groupId.get().isV1() && message.isGroupV1Update() && groupDatabase.groupExists(groupId.get().requireV1().deriveV2MigrationGroupId())) {
warn(String.valueOf(content.getTimestamp()), "Ignoring V1 update for a group we've already migrated to V2.");
return true;
}
if (groupId.isPresent() && groupDatabase.isUnknownGroup(groupId.get())) {
return sender.isBlocked();
}
boolean isTextMessage = message.getBody().isPresent();
boolean isMediaMessage = message.getAttachments().isPresent() || message.getQuote().isPresent() || message.getSharedContacts().isPresent() || message.getSticker().isPresent();
boolean isExpireMessage = message.isExpirationUpdate();
boolean isGv2Update = message.isGroupV2Update();
boolean isContentMessage = !message.isGroupV1Update() && !isGv2Update && !isExpireMessage && (isTextMessage || isMediaMessage);
boolean isGroupActive = groupId.isPresent() && groupDatabase.isActive(groupId.get());
boolean isLeaveMessage = message.getGroupContext().isPresent() && message.getGroupContext().get().getGroupV1Type() == SignalServiceGroup.Type.QUIT;
return (isContentMessage && !isGroupActive) || (sender.isBlocked() && !isLeaveMessage && !isGv2Update);
} else {
return sender.isBlocked();
}
} else if (content.getCallMessage().isPresent()) {
return sender.isBlocked();
} else if (content.getTypingMessage().isPresent()) {
if (sender.isBlocked()) {
return true;
}
if (content.getTypingMessage().get().getGroupId().isPresent()) {
GroupId groupId = GroupId.push(content.getTypingMessage().get().getGroupId().get());
Recipient groupRecipient = Recipient.externalPossiblyMigratedGroup(context, groupId);
if (groupRecipient.isBlocked() || !groupRecipient.isActiveGroup()) {
return true;
} else {
Optional<GroupRecord> groupRecord = SignalDatabase.groups().getGroup(groupId);
return groupRecord.isPresent() && groupRecord.get().isAnnouncementGroup() && !groupRecord.get().getAdmins().contains(sender);
}
}
}
return false;
}
use of org.whispersystems.signalservice.api.messages.SignalServiceDataMessage in project Signal-Android by WhisperSystems.
the class PushMediaSendJob method deliver.
private void deliver(MasterSecret masterSecret, OutgoingMediaMessage message) throws RetryLaterException, InsecureFallbackApprovalException, UntrustedIdentityException, UndeliverableMessageException {
if (message.getRecipients() == null || message.getRecipients().getPrimaryRecipient() == null || message.getRecipients().getPrimaryRecipient().getNumber() == null) {
throw new UndeliverableMessageException("No destination address.");
}
SignalServiceMessageSender messageSender = messageSenderFactory.create();
try {
SignalServiceAddress address = getPushAddress(message.getRecipients().getPrimaryRecipient().getNumber());
List<Attachment> scaledAttachments = scaleAttachments(masterSecret, MediaConstraints.PUSH_CONSTRAINTS, message.getAttachments());
List<SignalServiceAttachment> attachmentStreams = getAttachmentsFor(masterSecret, scaledAttachments);
SignalServiceDataMessage mediaMessage = SignalServiceDataMessage.newBuilder().withBody(message.getBody()).withAttachments(attachmentStreams).withTimestamp(message.getSentTimeMillis()).withExpiration((int) (message.getExpiresIn() / 1000)).asExpirationUpdate(message.isExpirationUpdate()).build();
messageSender.sendMessage(address, mediaMessage);
} catch (InvalidNumberException | UnregisteredUserException e) {
Log.w(TAG, e);
throw new InsecureFallbackApprovalException(e);
} catch (FileNotFoundException e) {
Log.w(TAG, e);
throw new UndeliverableMessageException(e);
} catch (IOException e) {
Log.w(TAG, e);
throw new RetryLaterException(e);
}
}
Aggregations