use of org.whispersystems.signalservice.api.messages.SignalServiceDataMessage 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.whispersystems.signalservice.api.messages.SignalServiceDataMessage in project Signal-Android by signalapp.
the class PushGroupSilentUpdateSendJob method deliver.
@NonNull
private List<Recipient> deliver(@NonNull List<Recipient> destinations, @NonNull GroupId.V2 groupId) throws IOException, UntrustedIdentityException {
SignalServiceGroupV2 group = SignalServiceGroupV2.fromProtobuf(groupContextV2);
SignalServiceDataMessage groupDataMessage = SignalServiceDataMessage.newBuilder().withTimestamp(timestamp).asGroupMessage(group).build();
List<SendMessageResult> results = GroupSendUtil.sendUnresendableDataMessage(context, groupId, destinations, false, ContentHint.IMPLICIT, groupDataMessage);
return GroupSendJobHelper.getCompletedSends(destinations, results);
}
use of org.whispersystems.signalservice.api.messages.SignalServiceDataMessage 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);
}
}
use of org.whispersystems.signalservice.api.messages.SignalServiceDataMessage in project Signal-Android by signalapp.
the class PushGroupUpdateJob method onRun.
@Override
public void onRun() throws IOException, UntrustedIdentityException {
if (!Recipient.self().isRegistered()) {
throw new NotPushRegisteredException();
}
Recipient sourceRecipient = Recipient.resolved(source);
if (sourceRecipient.isUnregistered()) {
Log.w(TAG, sourceRecipient.getId() + " not registered!");
return;
}
GroupDatabase groupDatabase = SignalDatabase.groups();
Optional<GroupRecord> record = groupDatabase.getGroup(groupId);
SignalServiceAttachment avatar = null;
if (record == null || !record.isPresent()) {
Log.w(TAG, "No information for group record info request: " + groupId.toString());
return;
}
if (AvatarHelper.hasAvatar(context, record.get().getRecipientId())) {
avatar = SignalServiceAttachmentStream.newStreamBuilder().withContentType("image/jpeg").withStream(AvatarHelper.getAvatar(context, record.get().getRecipientId())).withLength(AvatarHelper.getAvatarLength(context, record.get().getRecipientId())).build();
}
List<SignalServiceAddress> members = new LinkedList<>();
for (RecipientId member : record.get().getMembers()) {
Recipient recipient = Recipient.resolved(member);
if (recipient.isMaybeRegistered()) {
members.add(RecipientUtil.toSignalServiceAddress(context, recipient));
}
}
SignalServiceGroup groupContext = SignalServiceGroup.newBuilder(Type.UPDATE).withAvatar(avatar).withId(groupId.getDecodedId()).withMembers(members).withName(record.get().getTitle()).build();
RecipientId groupRecipientId = SignalDatabase.recipients().getOrInsertFromGroupId(groupId);
Recipient groupRecipient = Recipient.resolved(groupRecipientId);
SignalServiceDataMessage message = SignalServiceDataMessage.newBuilder().asGroupMessage(groupContext).withTimestamp(System.currentTimeMillis()).withExpiration(groupRecipient.getExpiresInSeconds()).build();
SignalServiceMessageSender messageSender = ApplicationDependencies.getSignalServiceMessageSender();
messageSender.sendDataMessage(RecipientUtil.toSignalServiceAddress(context, sourceRecipient), UnidentifiedAccessUtil.getAccessFor(context, sourceRecipient), ContentHint.DEFAULT, message, IndividualSendEvents.EMPTY);
}
Aggregations