Search in sources :

Example 1 with OutgoingGroupMediaMessage

use of org.thoughtcrime.securesms.mms.OutgoingGroupMediaMessage in project Signal-Android by WhisperSystems.

the class PushGroupSendJob method deliver.

private void deliver(MasterSecret masterSecret, OutgoingMediaMessage message, long filterRecipientId) throws IOException, RecipientFormattingException, InvalidNumberException, EncapsulatedExceptions, UndeliverableMessageException {
    SignalServiceMessageSender messageSender = messageSenderFactory.create();
    byte[] groupId = GroupUtil.getDecodedId(message.getRecipients().getPrimaryRecipient().getNumber());
    Recipients recipients = DatabaseFactory.getGroupDatabase(context).getGroupMembers(groupId, false);
    List<Attachment> scaledAttachments = scaleAttachments(masterSecret, MediaConstraints.PUSH_CONSTRAINTS, message.getAttachments());
    List<SignalServiceAttachment> attachmentStreams = getAttachmentsFor(masterSecret, scaledAttachments);
    List<SignalServiceAddress> addresses;
    if (filterRecipientId >= 0)
        addresses = getPushAddresses(filterRecipientId);
    else
        addresses = getPushAddresses(recipients);
    if (message.isGroup()) {
        OutgoingGroupMediaMessage groupMessage = (OutgoingGroupMediaMessage) message;
        GroupContext groupContext = groupMessage.getGroupContext();
        SignalServiceAttachment avatar = attachmentStreams.isEmpty() ? null : attachmentStreams.get(0);
        SignalServiceGroup.Type type = groupMessage.isGroupQuit() ? SignalServiceGroup.Type.QUIT : SignalServiceGroup.Type.UPDATE;
        SignalServiceGroup group = new SignalServiceGroup(type, groupId, groupContext.getName(), groupContext.getMembersList(), avatar);
        SignalServiceDataMessage groupDataMessage = new SignalServiceDataMessage(message.getSentTimeMillis(), group, null, null);
        messageSender.sendMessage(addresses, groupDataMessage);
    } else {
        SignalServiceGroup group = new SignalServiceGroup(groupId);
        SignalServiceDataMessage groupMessage = new SignalServiceDataMessage(message.getSentTimeMillis(), group, attachmentStreams, message.getBody(), false, (int) (message.getExpiresIn() / 1000), message.isExpirationUpdate());
        messageSender.sendMessage(addresses, groupMessage);
    }
}
Also used : Recipients(org.thoughtcrime.securesms.recipients.Recipients) SignalServiceMessageSender(org.whispersystems.signalservice.api.SignalServiceMessageSender) SignalServiceAttachment(org.whispersystems.signalservice.api.messages.SignalServiceAttachment) Attachment(org.thoughtcrime.securesms.attachments.Attachment) SignalServiceAttachment(org.whispersystems.signalservice.api.messages.SignalServiceAttachment) SignalServiceDataMessage(org.whispersystems.signalservice.api.messages.SignalServiceDataMessage) OutgoingGroupMediaMessage(org.thoughtcrime.securesms.mms.OutgoingGroupMediaMessage) SignalServiceAddress(org.whispersystems.signalservice.api.push.SignalServiceAddress) SignalServiceGroup(org.whispersystems.signalservice.api.messages.SignalServiceGroup) GroupContext(org.whispersystems.signalservice.internal.push.SignalServiceProtos.GroupContext)

Example 2 with OutgoingGroupMediaMessage

use of org.thoughtcrime.securesms.mms.OutgoingGroupMediaMessage in project Signal-Android by signalapp.

the class PushGroupSendJob method deliver.

private void deliver(OutgoingMediaMessage message, @Nullable Address filterAddress) throws IOException, RecipientFormattingException, InvalidNumberException, EncapsulatedExceptions, UndeliverableMessageException {
    String groupId = message.getRecipient().getAddress().toGroupString();
    Optional<byte[]> profileKey = getProfileKey(message.getRecipient());
    List<Address> recipients = getGroupMessageRecipients(groupId, messageId);
    MediaConstraints mediaConstraints = MediaConstraints.getPushMediaConstraints();
    List<Attachment> scaledAttachments = scaleAttachments(mediaConstraints, message.getAttachments());
    List<SignalServiceAttachment> attachmentStreams = getAttachmentsFor(scaledAttachments);
    List<SignalServiceAddress> addresses;
    if (filterAddress != null)
        addresses = getPushAddresses(filterAddress);
    else
        addresses = getPushAddresses(recipients);
    if (message.isGroup()) {
        OutgoingGroupMediaMessage groupMessage = (OutgoingGroupMediaMessage) message;
        GroupContext groupContext = groupMessage.getGroupContext();
        SignalServiceAttachment avatar = attachmentStreams.isEmpty() ? null : attachmentStreams.get(0);
        SignalServiceGroup.Type type = groupMessage.isGroupQuit() ? SignalServiceGroup.Type.QUIT : SignalServiceGroup.Type.UPDATE;
        SignalServiceGroup group = new SignalServiceGroup(type, GroupUtil.getDecodedId(groupId), groupContext.getName(), groupContext.getMembersList(), avatar);
        SignalServiceDataMessage groupDataMessage = SignalServiceDataMessage.newBuilder().withTimestamp(message.getSentTimeMillis()).asGroupMessage(group).build();
        messageSender.sendMessage(addresses, groupDataMessage);
    } else {
        SignalServiceGroup group = new SignalServiceGroup(GroupUtil.getDecodedId(groupId));
        SignalServiceDataMessage groupMessage = SignalServiceDataMessage.newBuilder().withTimestamp(message.getSentTimeMillis()).asGroupMessage(group).withAttachments(attachmentStreams).withBody(message.getBody()).withExpiration((int) (message.getExpiresIn() / 1000)).asExpirationUpdate(message.isExpirationUpdate()).withProfileKey(profileKey.orNull()).build();
        messageSender.sendMessage(addresses, groupMessage);
    }
}
Also used : Address(org.thoughtcrime.securesms.database.Address) SignalServiceAddress(org.whispersystems.signalservice.api.push.SignalServiceAddress) SignalServiceAttachment(org.whispersystems.signalservice.api.messages.SignalServiceAttachment) Attachment(org.thoughtcrime.securesms.attachments.Attachment) SignalServiceAttachment(org.whispersystems.signalservice.api.messages.SignalServiceAttachment) SignalServiceDataMessage(org.whispersystems.signalservice.api.messages.SignalServiceDataMessage) OutgoingGroupMediaMessage(org.thoughtcrime.securesms.mms.OutgoingGroupMediaMessage) MediaConstraints(org.thoughtcrime.securesms.mms.MediaConstraints) SignalServiceAddress(org.whispersystems.signalservice.api.push.SignalServiceAddress) SignalServiceGroup(org.whispersystems.signalservice.api.messages.SignalServiceGroup) GroupContext(org.whispersystems.signalservice.internal.push.SignalServiceProtos.GroupContext)

Example 3 with OutgoingGroupMediaMessage

use of org.thoughtcrime.securesms.mms.OutgoingGroupMediaMessage in project Signal-Android by signalapp.

the class MmsDatabase method insertMessageOutbox.

public long insertMessageOutbox(@NonNull OutgoingMediaMessage message, long threadId, boolean forceSms, @Nullable SmsDatabase.InsertListener insertListener) throws MmsException {
    long type = Types.BASE_SENDING_TYPE;
    if (message.isSecure())
        type |= (Types.SECURE_MESSAGE_BIT | Types.PUSH_MESSAGE_BIT);
    if (forceSms)
        type |= Types.MESSAGE_FORCE_SMS_BIT;
    if (message.isGroup()) {
        if (((OutgoingGroupMediaMessage) message).isGroupUpdate())
            type |= Types.GROUP_UPDATE_BIT;
        else if (((OutgoingGroupMediaMessage) message).isGroupQuit())
            type |= Types.GROUP_QUIT_BIT;
    }
    if (message.isExpirationUpdate()) {
        type |= Types.EXPIRATION_TIMER_UPDATE_BIT;
    }
    Map<Address, Long> earlyDeliveryReceipts = earlyDeliveryReceiptCache.remove(message.getSentTimeMillis());
    Map<Address, Long> earlyReadReceipts = earlyReadReceiptCache.remove(message.getSentTimeMillis());
    ContentValues contentValues = new ContentValues();
    contentValues.put(DATE_SENT, message.getSentTimeMillis());
    contentValues.put(MESSAGE_TYPE, PduHeaders.MESSAGE_TYPE_SEND_REQ);
    contentValues.put(MESSAGE_BOX, type);
    contentValues.put(THREAD_ID, threadId);
    contentValues.put(READ, 1);
    contentValues.put(DATE_RECEIVED, System.currentTimeMillis());
    contentValues.put(SUBSCRIPTION_ID, message.getSubscriptionId());
    contentValues.put(EXPIRES_IN, message.getExpiresIn());
    contentValues.put(ADDRESS, message.getRecipient().getAddress().serialize());
    contentValues.put(DELIVERY_RECEIPT_COUNT, Stream.of(earlyDeliveryReceipts.values()).mapToLong(Long::longValue).sum());
    contentValues.put(READ_RECEIPT_COUNT, Stream.of(earlyReadReceipts.values()).mapToLong(Long::longValue).sum());
    long messageId = insertMediaMessage(message.getBody(), message.getAttachments(), contentValues, insertListener);
    if (message.getRecipient().getAddress().isGroup()) {
        List<Recipient> members = DatabaseFactory.getGroupDatabase(context).getGroupMembers(message.getRecipient().getAddress().toGroupString(), false);
        GroupReceiptDatabase receiptDatabase = DatabaseFactory.getGroupReceiptDatabase(context);
        receiptDatabase.insert(Stream.of(members).map(Recipient::getAddress).toList(), messageId, GroupReceiptDatabase.STATUS_UNDELIVERED, message.getSentTimeMillis());
        for (Address address : earlyDeliveryReceipts.keySet()) receiptDatabase.update(address, messageId, GroupReceiptDatabase.STATUS_DELIVERED, -1);
        for (Address address : earlyReadReceipts.keySet()) receiptDatabase.update(address, messageId, GroupReceiptDatabase.STATUS_READ, -1);
    }
    DatabaseFactory.getThreadDatabase(context).setLastSeen(threadId);
    DatabaseFactory.getThreadDatabase(context).setHasSent(threadId, true);
    jobManager.add(new TrimThreadJob(context, threadId));
    return messageId;
}
Also used : ContentValues(android.content.ContentValues) TrimThreadJob(org.thoughtcrime.securesms.jobs.TrimThreadJob) OutgoingGroupMediaMessage(org.thoughtcrime.securesms.mms.OutgoingGroupMediaMessage) Recipient(org.thoughtcrime.securesms.recipients.Recipient)

Example 4 with OutgoingGroupMediaMessage

use of org.thoughtcrime.securesms.mms.OutgoingGroupMediaMessage in project Signal-Android by WhisperSystems.

the class MmsDatabase method insertMessageOutbox.

public long insertMessageOutbox(@NonNull MasterSecretUnion masterSecret, @NonNull OutgoingMediaMessage message, long threadId, boolean forceSms) throws MmsException {
    long type = Types.BASE_SENDING_TYPE;
    if (masterSecret.getMasterSecret().isPresent())
        type |= Types.ENCRYPTION_SYMMETRIC_BIT;
    else
        type |= Types.ENCRYPTION_ASYMMETRIC_BIT;
    if (message.isSecure())
        type |= (Types.SECURE_MESSAGE_BIT | Types.PUSH_MESSAGE_BIT);
    if (forceSms)
        type |= Types.MESSAGE_FORCE_SMS_BIT;
    if (message.isGroup()) {
        if (((OutgoingGroupMediaMessage) message).isGroupUpdate())
            type |= Types.GROUP_UPDATE_BIT;
        else if (((OutgoingGroupMediaMessage) message).isGroupQuit())
            type |= Types.GROUP_QUIT_BIT;
    }
    if (message.isExpirationUpdate()) {
        type |= Types.EXPIRATION_TIMER_UPDATE_BIT;
    }
    List<String> recipientNumbers = message.getRecipients().toNumberStringList(true);
    MmsAddresses addresses;
    if (!message.getRecipients().isSingleRecipient() && message.getDistributionType() == ThreadDatabase.DistributionTypes.BROADCAST) {
        addresses = MmsAddresses.forBcc(recipientNumbers);
    } else {
        addresses = MmsAddresses.forTo(recipientNumbers);
    }
    ContentValues contentValues = new ContentValues();
    contentValues.put(DATE_SENT, message.getSentTimeMillis());
    contentValues.put(MESSAGE_TYPE, PduHeaders.MESSAGE_TYPE_SEND_REQ);
    contentValues.put(MESSAGE_BOX, type);
    contentValues.put(THREAD_ID, threadId);
    contentValues.put(READ, 1);
    contentValues.put(DATE_RECEIVED, System.currentTimeMillis());
    contentValues.put(SUBSCRIPTION_ID, message.getSubscriptionId());
    contentValues.put(EXPIRES_IN, message.getExpiresIn());
    if (message.getRecipients().isSingleRecipient()) {
        try {
            contentValues.put(RECEIPT_COUNT, earlyReceiptCache.remove(message.getSentTimeMillis(), canonicalizeNumber(context, message.getRecipients().getPrimaryRecipient().getNumber())));
        } catch (InvalidNumberException e) {
            Log.w(TAG, e);
        }
    }
    contentValues.remove(ADDRESS);
    long messageId = insertMediaMessage(masterSecret, addresses, message.getBody(), message.getAttachments(), contentValues);
    DatabaseFactory.getThreadDatabase(context).setLastSeen(threadId);
    jobManager.add(new TrimThreadJob(context, threadId));
    return messageId;
}
Also used : ContentValues(android.content.ContentValues) TrimThreadJob(org.thoughtcrime.securesms.jobs.TrimThreadJob) OutgoingGroupMediaMessage(org.thoughtcrime.securesms.mms.OutgoingGroupMediaMessage) InvalidNumberException(org.whispersystems.signalservice.api.util.InvalidNumberException)

Example 5 with OutgoingGroupMediaMessage

use of org.thoughtcrime.securesms.mms.OutgoingGroupMediaMessage in project Signal-Android by WhisperSystems.

the class MmsDatabase method getOutgoingMessage.

public OutgoingMediaMessage getOutgoingMessage(MasterSecret masterSecret, long messageId) throws MmsException, NoSuchMessageException {
    MmsAddressDatabase addr = DatabaseFactory.getMmsAddressDatabase(context);
    AttachmentDatabase attachmentDatabase = DatabaseFactory.getAttachmentDatabase(context);
    Cursor cursor = null;
    try {
        cursor = rawQuery(RAW_ID_WHERE, new String[] { String.valueOf(messageId) });
        if (cursor != null && cursor.moveToNext()) {
            long outboxType = cursor.getLong(cursor.getColumnIndexOrThrow(MESSAGE_BOX));
            String messageText = cursor.getString(cursor.getColumnIndexOrThrow(BODY));
            long timestamp = cursor.getLong(cursor.getColumnIndexOrThrow(NORMALIZED_DATE_SENT));
            int subscriptionId = cursor.getInt(cursor.getColumnIndexOrThrow(SUBSCRIPTION_ID));
            long expiresIn = cursor.getLong(cursor.getColumnIndexOrThrow(EXPIRES_IN));
            List<Attachment> attachments = new LinkedList<Attachment>(attachmentDatabase.getAttachmentsForMessage(messageId));
            MmsAddresses addresses = addr.getAddressesForId(messageId);
            List<String> destinations = new LinkedList<>();
            String body = getDecryptedBody(masterSecret, messageText, outboxType);
            destinations.addAll(addresses.getBcc());
            destinations.addAll(addresses.getCc());
            destinations.addAll(addresses.getTo());
            Recipients recipients = RecipientFactory.getRecipientsFromStrings(context, destinations, false);
            if (body != null && (Types.isGroupQuit(outboxType) || Types.isGroupUpdate(outboxType))) {
                return new OutgoingGroupMediaMessage(recipients, body, attachments, timestamp, 0);
            } else if (Types.isExpirationTimerUpdate(outboxType)) {
                return new OutgoingExpirationUpdateMessage(recipients, timestamp, expiresIn);
            }
            OutgoingMediaMessage message = new OutgoingMediaMessage(recipients, body, attachments, timestamp, subscriptionId, expiresIn, !addresses.getBcc().isEmpty() ? ThreadDatabase.DistributionTypes.BROADCAST : ThreadDatabase.DistributionTypes.DEFAULT);
            if (Types.isSecureType(outboxType)) {
                return new OutgoingSecureMediaMessage(message);
            }
            return message;
        }
        throw new NoSuchMessageException("No record found for id: " + messageId);
    } catch (IOException e) {
        throw new MmsException(e);
    } finally {
        if (cursor != null)
            cursor.close();
    }
}
Also used : Recipients(org.thoughtcrime.securesms.recipients.Recipients) Attachment(org.thoughtcrime.securesms.attachments.Attachment) DatabaseAttachment(org.thoughtcrime.securesms.attachments.DatabaseAttachment) MmsNotificationAttachment(org.thoughtcrime.securesms.attachments.MmsNotificationAttachment) OutgoingMediaMessage(org.thoughtcrime.securesms.mms.OutgoingMediaMessage) IOException(java.io.IOException) Cursor(android.database.Cursor) LinkedList(java.util.LinkedList) OutgoingSecureMediaMessage(org.thoughtcrime.securesms.mms.OutgoingSecureMediaMessage) MmsException(ws.com.google.android.mms.MmsException) OutgoingGroupMediaMessage(org.thoughtcrime.securesms.mms.OutgoingGroupMediaMessage) OutgoingExpirationUpdateMessage(org.thoughtcrime.securesms.mms.OutgoingExpirationUpdateMessage)

Aggregations

OutgoingGroupMediaMessage (org.thoughtcrime.securesms.mms.OutgoingGroupMediaMessage)12 Attachment (org.thoughtcrime.securesms.attachments.Attachment)6 GroupContext (org.whispersystems.signalservice.internal.push.SignalServiceProtos.GroupContext)6 ByteString (com.google.protobuf.ByteString)5 IOException (java.io.IOException)5 Recipient (org.thoughtcrime.securesms.recipients.Recipient)4 Recipients (org.thoughtcrime.securesms.recipients.Recipients)4 LinkedList (java.util.LinkedList)3 Address (org.thoughtcrime.securesms.database.Address)3 ContentValues (android.content.ContentValues)2 Context (android.content.Context)2 Cursor (android.database.Cursor)2 Uri (android.net.Uri)2 Nullable (android.support.annotation.Nullable)2 AlertDialog (android.support.v7.app.AlertDialog)2 DatabaseAttachment (org.thoughtcrime.securesms.attachments.DatabaseAttachment)2 MmsNotificationAttachment (org.thoughtcrime.securesms.attachments.MmsNotificationAttachment)2 UriAttachment (org.thoughtcrime.securesms.attachments.UriAttachment)2 InsertResult (org.thoughtcrime.securesms.database.MessagingDatabase.InsertResult)2 MmsDatabase (org.thoughtcrime.securesms.database.MmsDatabase)2