Search in sources :

Example 26 with DatabaseAttachment

use of org.thoughtcrime.securesms.attachments.DatabaseAttachment in project Signal-Android by WhisperSystems.

the class MmsSendJob method enqueue.

/**
 * Enqueues compression jobs for attachments and finally the MMS send job.
 */
@WorkerThread
public static void enqueue(@NonNull Context context, @NonNull JobManager jobManager, long messageId) {
    MessageDatabase database = SignalDatabase.mms();
    OutgoingMediaMessage message;
    try {
        message = database.getOutgoingMessage(messageId);
    } catch (MmsException | NoSuchMessageException e) {
        throw new AssertionError(e);
    }
    List<Job> compressionJobs = Stream.of(message.getAttachments()).map(a -> (Job) AttachmentCompressionJob.fromAttachment((DatabaseAttachment) a, true, message.getSubscriptionId())).toList();
    MmsSendJob sendJob = new MmsSendJob(messageId);
    jobManager.startChain(compressionJobs).then(sendJob).enqueue();
}
Also used : SignalStore(org.thoughtcrime.securesms.keyvalue.SignalStore) NumberUtil(org.thoughtcrime.securesms.phonenumbers.NumberUtil) Arrays(java.util.Arrays) NonNull(androidx.annotation.NonNull) Data(org.thoughtcrime.securesms.jobmanager.Data) JobManager(org.thoughtcrime.securesms.jobmanager.JobManager) PduPart(com.google.android.mms.pdu_alt.PduPart) InsecureFallbackApprovalException(org.thoughtcrime.securesms.transport.InsecureFallbackApprovalException) Utils(com.klinker.android.send_message.Utils) SecureRandom(java.security.SecureRandom) SmilXmlSerializer(com.android.mms.dom.smil.parser.SmilXmlSerializer) Recipient(org.thoughtcrime.securesms.recipients.Recipient) PartAuthority(org.thoughtcrime.securesms.mms.PartAuthority) SendReq(com.google.android.mms.pdu_alt.SendReq) ApplicationDependencies(org.thoughtcrime.securesms.dependencies.ApplicationDependencies) GroupDatabase(org.thoughtcrime.securesms.database.GroupDatabase) UndeliverableMessageException(org.thoughtcrime.securesms.transport.UndeliverableMessageException) ThreadDatabase(org.thoughtcrime.securesms.database.ThreadDatabase) Log(org.signal.core.util.logging.Log) List(java.util.List) ContentType(com.google.android.mms.ContentType) SmilHelper(com.google.android.mms.smil.SmilHelper) Job(org.thoughtcrime.securesms.jobmanager.Job) MessageDatabase(org.thoughtcrime.securesms.database.MessageDatabase) NoSuchMessageException(org.thoughtcrime.securesms.database.NoSuchMessageException) Attachment(org.thoughtcrime.securesms.attachments.Attachment) OutgoingMediaMessage(org.thoughtcrime.securesms.mms.OutgoingMediaMessage) Context(android.content.Context) SignalDatabase(org.thoughtcrime.securesms.database.SignalDatabase) Stream(com.annimon.stream.Stream) ByteArrayOutputStream(java.io.ByteArrayOutputStream) Util(org.thoughtcrime.securesms.util.Util) JobLogger(org.thoughtcrime.securesms.jobmanager.JobLogger) WorkerThread(androidx.annotation.WorkerThread) DatabaseAttachment(org.thoughtcrime.securesms.attachments.DatabaseAttachment) InvalidHeaderValueException(com.google.android.mms.InvalidHeaderValueException) PduHeaders(com.google.android.mms.pdu_alt.PduHeaders) StreamUtil(org.signal.core.util.StreamUtil) MmsException(org.thoughtcrime.securesms.mms.MmsException) EncodedStringValue(com.google.android.mms.pdu_alt.EncodedStringValue) TextUtils(android.text.TextUtils) NetworkConstraint(org.thoughtcrime.securesms.jobmanager.impl.NetworkConstraint) Hex(org.thoughtcrime.securesms.util.Hex) IOException(java.io.IOException) SendConf(com.google.android.mms.pdu_alt.SendConf) MediaConstraints(org.thoughtcrime.securesms.mms.MediaConstraints) CharacterSets(com.google.android.mms.pdu_alt.CharacterSets) PduComposer(com.google.android.mms.pdu_alt.PduComposer) CompatMmsConnection(org.thoughtcrime.securesms.mms.CompatMmsConnection) MmsSendResult(org.thoughtcrime.securesms.mms.MmsSendResult) MimeTypeMap(android.webkit.MimeTypeMap) PduBody(com.google.android.mms.pdu_alt.PduBody) MessageDatabase(org.thoughtcrime.securesms.database.MessageDatabase) MmsException(org.thoughtcrime.securesms.mms.MmsException) NoSuchMessageException(org.thoughtcrime.securesms.database.NoSuchMessageException) DatabaseAttachment(org.thoughtcrime.securesms.attachments.DatabaseAttachment) OutgoingMediaMessage(org.thoughtcrime.securesms.mms.OutgoingMediaMessage) Job(org.thoughtcrime.securesms.jobmanager.Job) WorkerThread(androidx.annotation.WorkerThread)

Example 27 with DatabaseAttachment

use of org.thoughtcrime.securesms.attachments.DatabaseAttachment in project Signal-Android by WhisperSystems.

the class MessageContentProcessor method handleMediaMessage.

@Nullable
private MessageId handleMediaMessage(@NonNull SignalServiceContent content, @NonNull SignalServiceDataMessage message, @NonNull Optional<Long> smsMessageId, @NonNull Recipient senderRecipient, @NonNull Recipient threadRecipient, long receivedTime) throws StorageFailedException {
    log(message.getTimestamp(), "Media message.");
    notifyTypingStoppedFromIncomingMessage(senderRecipient, threadRecipient, content.getSenderDevice());
    Optional<InsertResult> insertResult;
    MessageDatabase database = SignalDatabase.mms();
    database.beginTransaction();
    try {
        Optional<QuoteModel> quote = getValidatedQuote(message.getQuote());
        Optional<List<Contact>> sharedContacts = getContacts(message.getSharedContacts());
        Optional<List<LinkPreview>> linkPreviews = getLinkPreviews(message.getPreviews(), message.getBody().or(""));
        Optional<List<Mention>> mentions = getMentions(message.getMentions());
        Optional<Attachment> sticker = getStickerAttachment(message.getSticker());
        IncomingMediaMessage mediaMessage = new IncomingMediaMessage(senderRecipient.getId(), message.getTimestamp(), content.getServerReceivedTimestamp(), receivedTime, -1, TimeUnit.SECONDS.toMillis(message.getExpiresInSeconds()), false, message.isViewOnce(), content.isNeedsReceipt(), message.getBody(), message.getGroupContext(), message.getAttachments(), quote, sharedContacts, linkPreviews, mentions, sticker, content.getServerUuid());
        insertResult = database.insertSecureDecryptedMessageInbox(mediaMessage, -1);
        if (insertResult.isPresent()) {
            if (smsMessageId.isPresent()) {
                SignalDatabase.sms().deleteMessage(smsMessageId.get());
            }
            database.setTransactionSuccessful();
        }
    } catch (MmsException e) {
        throw new StorageFailedException(e, content.getSender().getIdentifier(), content.getSenderDevice());
    } finally {
        database.endTransaction();
    }
    if (insertResult.isPresent()) {
        List<DatabaseAttachment> allAttachments = SignalDatabase.attachments().getAttachmentsForMessage(insertResult.get().getMessageId());
        List<DatabaseAttachment> stickerAttachments = Stream.of(allAttachments).filter(Attachment::isSticker).toList();
        List<DatabaseAttachment> attachments = Stream.of(allAttachments).filterNot(Attachment::isSticker).toList();
        forceStickerDownloadIfNecessary(insertResult.get().getMessageId(), stickerAttachments);
        for (DatabaseAttachment attachment : attachments) {
            ApplicationDependencies.getJobManager().add(new AttachmentDownloadJob(insertResult.get().getMessageId(), attachment.getAttachmentId(), false));
        }
        ApplicationDependencies.getMessageNotifier().updateNotification(context, insertResult.get().getThreadId());
        TrimThreadJob.enqueueAsync(insertResult.get().getThreadId());
        if (message.isViewOnce()) {
            ApplicationDependencies.getViewOnceMessageManager().scheduleIfNecessary();
        }
        return new MessageId(insertResult.get().getMessageId(), true);
    } else {
        return null;
    }
}
Also used : InsertResult(org.thoughtcrime.securesms.database.MessageDatabase.InsertResult) MessageDatabase(org.thoughtcrime.securesms.database.MessageDatabase) IncomingMediaMessage(org.thoughtcrime.securesms.mms.IncomingMediaMessage) DatabaseAttachment(org.thoughtcrime.securesms.attachments.DatabaseAttachment) SignalServiceAttachment(org.whispersystems.signalservice.api.messages.SignalServiceAttachment) Attachment(org.thoughtcrime.securesms.attachments.Attachment) PointerAttachment(org.thoughtcrime.securesms.attachments.PointerAttachment) DatabaseAttachment(org.thoughtcrime.securesms.attachments.DatabaseAttachment) UriAttachment(org.thoughtcrime.securesms.attachments.UriAttachment) TombstoneAttachment(org.thoughtcrime.securesms.attachments.TombstoneAttachment) QuoteModel(org.thoughtcrime.securesms.mms.QuoteModel) MmsException(org.thoughtcrime.securesms.mms.MmsException) AttachmentDownloadJob(org.thoughtcrime.securesms.jobs.AttachmentDownloadJob) ArrayList(java.util.ArrayList) List(java.util.List) LinkedList(java.util.LinkedList) MessageId(org.thoughtcrime.securesms.database.model.MessageId) SyncMessageId(org.thoughtcrime.securesms.database.MessageDatabase.SyncMessageId) Nullable(androidx.annotation.Nullable)

Example 28 with DatabaseAttachment

use of org.thoughtcrime.securesms.attachments.DatabaseAttachment in project Signal-Android by WhisperSystems.

the class MessageContentProcessor method handleSynchronizeSentMediaMessage.

private long handleSynchronizeSentMediaMessage(@NonNull SentTranscriptMessage message, long envelopeTimestamp) throws MmsException, BadGroupIdException {
    log(envelopeTimestamp, "Synchronize sent media message for " + message.getTimestamp());
    MessageDatabase database = SignalDatabase.mms();
    Recipient recipients = getSyncMessageDestination(message);
    Optional<QuoteModel> quote = getValidatedQuote(message.getMessage().getQuote());
    Optional<Attachment> sticker = getStickerAttachment(message.getMessage().getSticker());
    Optional<List<Contact>> sharedContacts = getContacts(message.getMessage().getSharedContacts());
    Optional<List<LinkPreview>> previews = getLinkPreviews(message.getMessage().getPreviews(), message.getMessage().getBody().or(""));
    Optional<List<Mention>> mentions = getMentions(message.getMessage().getMentions());
    boolean viewOnce = message.getMessage().isViewOnce();
    List<Attachment> syncAttachments = viewOnce ? Collections.singletonList(new TombstoneAttachment(MediaUtil.VIEW_ONCE, false)) : PointerAttachment.forPointers(message.getMessage().getAttachments());
    if (sticker.isPresent()) {
        syncAttachments.add(sticker.get());
    }
    OutgoingMediaMessage mediaMessage = new OutgoingMediaMessage(recipients, message.getMessage().getBody().orNull(), syncAttachments, message.getTimestamp(), -1, TimeUnit.SECONDS.toMillis(message.getMessage().getExpiresInSeconds()), viewOnce, ThreadDatabase.DistributionTypes.DEFAULT, quote.orNull(), sharedContacts.or(Collections.emptyList()), previews.or(Collections.emptyList()), mentions.or(Collections.emptyList()), Collections.emptySet(), Collections.emptySet());
    mediaMessage = new OutgoingSecureMediaMessage(mediaMessage);
    if (recipients.getExpiresInSeconds() != message.getMessage().getExpiresInSeconds()) {
        handleSynchronizeSentExpirationUpdate(message);
    }
    long threadId = SignalDatabase.threads().getOrCreateThreadIdFor(recipients);
    long messageId;
    List<DatabaseAttachment> attachments;
    List<DatabaseAttachment> stickerAttachments;
    database.beginTransaction();
    try {
        messageId = database.insertMessageOutbox(mediaMessage, threadId, false, GroupReceiptDatabase.STATUS_UNKNOWN, null);
        if (recipients.isGroup()) {
            updateGroupReceiptStatus(message, messageId, recipients.requireGroupId());
        } else {
            database.markUnidentified(messageId, isUnidentified(message, recipients));
        }
        database.markAsSent(messageId, true);
        List<DatabaseAttachment> allAttachments = SignalDatabase.attachments().getAttachmentsForMessage(messageId);
        stickerAttachments = Stream.of(allAttachments).filter(Attachment::isSticker).toList();
        attachments = Stream.of(allAttachments).filterNot(Attachment::isSticker).toList();
        if (message.getMessage().getExpiresInSeconds() > 0) {
            database.markExpireStarted(messageId, message.getExpirationStartTimestamp());
            ApplicationDependencies.getExpiringMessageManager().scheduleDeletion(messageId, true, message.getExpirationStartTimestamp(), TimeUnit.SECONDS.toMillis(message.getMessage().getExpiresInSeconds()));
        }
        if (recipients.isSelf()) {
            SyncMessageId id = new SyncMessageId(recipients.getId(), message.getTimestamp());
            SignalDatabase.mmsSms().incrementDeliveryReceiptCount(id, System.currentTimeMillis());
            SignalDatabase.mmsSms().incrementReadReceiptCount(id, System.currentTimeMillis());
        }
        database.setTransactionSuccessful();
    } finally {
        database.endTransaction();
    }
    for (DatabaseAttachment attachment : attachments) {
        ApplicationDependencies.getJobManager().add(new AttachmentDownloadJob(messageId, attachment.getAttachmentId(), false));
    }
    forceStickerDownloadIfNecessary(messageId, stickerAttachments);
    return threadId;
}
Also used : MessageDatabase(org.thoughtcrime.securesms.database.MessageDatabase) DatabaseAttachment(org.thoughtcrime.securesms.attachments.DatabaseAttachment) Recipient(org.thoughtcrime.securesms.recipients.Recipient) SignalServiceAttachment(org.whispersystems.signalservice.api.messages.SignalServiceAttachment) Attachment(org.thoughtcrime.securesms.attachments.Attachment) PointerAttachment(org.thoughtcrime.securesms.attachments.PointerAttachment) DatabaseAttachment(org.thoughtcrime.securesms.attachments.DatabaseAttachment) UriAttachment(org.thoughtcrime.securesms.attachments.UriAttachment) TombstoneAttachment(org.thoughtcrime.securesms.attachments.TombstoneAttachment) OutgoingMediaMessage(org.thoughtcrime.securesms.mms.OutgoingMediaMessage) QuoteModel(org.thoughtcrime.securesms.mms.QuoteModel) OutgoingSecureMediaMessage(org.thoughtcrime.securesms.mms.OutgoingSecureMediaMessage) TombstoneAttachment(org.thoughtcrime.securesms.attachments.TombstoneAttachment) AttachmentDownloadJob(org.thoughtcrime.securesms.jobs.AttachmentDownloadJob) ArrayList(java.util.ArrayList) List(java.util.List) LinkedList(java.util.LinkedList) SyncMessageId(org.thoughtcrime.securesms.database.MessageDatabase.SyncMessageId)

Example 29 with DatabaseAttachment

use of org.thoughtcrime.securesms.attachments.DatabaseAttachment in project Signal-Android by WhisperSystems.

the class MessageContentProcessor method forceStickerDownloadIfNecessary.

private void forceStickerDownloadIfNecessary(long messageId, List<DatabaseAttachment> stickerAttachments) {
    if (stickerAttachments.isEmpty())
        return;
    DatabaseAttachment stickerAttachment = stickerAttachments.get(0);
    if (stickerAttachment.getTransferState() != AttachmentDatabase.TRANSFER_PROGRESS_DONE) {
        AttachmentDownloadJob downloadJob = new AttachmentDownloadJob(messageId, stickerAttachment.getAttachmentId(), true);
        try {
            downloadJob.setContext(context);
            downloadJob.doWork();
        } catch (Exception e) {
            warn("Failed to download sticker inline. Scheduling.");
            ApplicationDependencies.getJobManager().add(downloadJob);
        }
    }
}
Also used : DatabaseAttachment(org.thoughtcrime.securesms.attachments.DatabaseAttachment) AttachmentDownloadJob(org.thoughtcrime.securesms.jobs.AttachmentDownloadJob) GroupChangeBusyException(org.thoughtcrime.securesms.groups.GroupChangeBusyException) IOException(java.io.IOException) SerializationException(com.mobilecoin.lib.exceptions.SerializationException) GroupNotAMemberException(org.thoughtcrime.securesms.groups.GroupNotAMemberException) BadGroupIdException(org.thoughtcrime.securesms.groups.BadGroupIdException) MmsException(org.thoughtcrime.securesms.mms.MmsException)

Example 30 with DatabaseAttachment

use of org.thoughtcrime.securesms.attachments.DatabaseAttachment in project Signal-Android by WhisperSystems.

the class ConversationDataSource method load.

@Override
@Nullable
public ConversationMessage load(@NonNull MessageId messageId) {
    Stopwatch stopwatch = new Stopwatch("load(" + messageId + "), thread " + threadId);
    MessageDatabase database = messageId.isMms() ? SignalDatabase.mms() : SignalDatabase.sms();
    MessageRecord record = database.getMessageRecordOrNull(messageId.getId());
    stopwatch.split("message");
    try {
        if (record != null) {
            List<Mention> mentions;
            if (messageId.isMms()) {
                mentions = SignalDatabase.mentions().getMentionsForMessage(messageId.getId());
            } else {
                mentions = Collections.emptyList();
            }
            stopwatch.split("mentions");
            List<ReactionRecord> reactions = SignalDatabase.reactions().getReactions(messageId);
            record = ReactionHelper.recordWithReactions(record, reactions);
            stopwatch.split("reactions");
            if (messageId.isMms()) {
                List<DatabaseAttachment> attachments = SignalDatabase.attachments().getAttachmentsForMessage(messageId.getId());
                if (attachments.size() > 0) {
                    record = ((MediaMmsMessageRecord) record).withAttachments(context, attachments);
                }
            }
            stopwatch.split("attachments");
            return ConversationMessage.ConversationMessageFactory.createWithUnresolvedData(ApplicationDependencies.getApplication(), record, mentions);
        } else {
            return null;
        }
    } finally {
        stopwatch.stop(TAG);
    }
}
Also used : MessageDatabase(org.thoughtcrime.securesms.database.MessageDatabase) Mention(org.thoughtcrime.securesms.database.model.Mention) Stopwatch(org.thoughtcrime.securesms.util.Stopwatch) DatabaseAttachment(org.thoughtcrime.securesms.attachments.DatabaseAttachment) MessageRecord(org.thoughtcrime.securesms.database.model.MessageRecord) MediaMmsMessageRecord(org.thoughtcrime.securesms.database.model.MediaMmsMessageRecord) InMemoryMessageRecord(org.thoughtcrime.securesms.database.model.InMemoryMessageRecord) SmsMessageRecord(org.thoughtcrime.securesms.database.model.SmsMessageRecord) ReactionRecord(org.thoughtcrime.securesms.database.model.ReactionRecord) Nullable(androidx.annotation.Nullable)

Aggregations

DatabaseAttachment (org.thoughtcrime.securesms.attachments.DatabaseAttachment)51 LinkedList (java.util.LinkedList)15 AttachmentId (org.thoughtcrime.securesms.attachments.AttachmentId)14 Attachment (org.thoughtcrime.securesms.attachments.Attachment)12 MmsException (org.thoughtcrime.securesms.mms.MmsException)11 NonNull (androidx.annotation.NonNull)10 AttachmentDatabase (org.thoughtcrime.securesms.database.AttachmentDatabase)10 ContentValues (android.content.ContentValues)9 OutgoingMediaMessage (org.thoughtcrime.securesms.mms.OutgoingMediaMessage)9 Nullable (androidx.annotation.Nullable)8 IOException (java.io.IOException)8 List (java.util.List)8 Recipient (org.thoughtcrime.securesms.recipients.Recipient)8 Cursor (android.database.Cursor)7 MessageDatabase (org.thoughtcrime.securesms.database.MessageDatabase)6 OutgoingSecureMediaMessage (org.thoughtcrime.securesms.mms.OutgoingSecureMediaMessage)6 Context (android.content.Context)5 HashMap (java.util.HashMap)5 Contact (org.thoughtcrime.securesms.contactshare.Contact)5 InputStream (java.io.InputStream)4