Search in sources :

Example 46 with DatabaseAttachment

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

the class PushDecryptJob method handleSynchronizeSentMediaMessage.

private long handleSynchronizeSentMediaMessage(@NonNull SentTranscriptMessage message) throws MmsException {
    MmsDatabase database = DatabaseFactory.getMmsDatabase(context);
    Recipient recipients = getSyncMessageDestination(message);
    OutgoingMediaMessage mediaMessage = new OutgoingMediaMessage(recipients, message.getMessage().getBody().orNull(), PointerAttachment.forPointers(message.getMessage().getAttachments()), message.getTimestamp(), -1, message.getMessage().getExpiresInSeconds() * 1000L, ThreadDatabase.DistributionTypes.DEFAULT);
    mediaMessage = new OutgoingSecureMediaMessage(mediaMessage);
    if (recipients.getExpireMessages() != message.getMessage().getExpiresInSeconds()) {
        handleSynchronizeSentExpirationUpdate(message);
    }
    long threadId = DatabaseFactory.getThreadDatabase(context).getThreadIdFor(recipients);
    long messageId = database.insertMessageOutbox(mediaMessage, threadId, false, null);
    database.markAsSent(messageId, true);
    for (DatabaseAttachment attachment : DatabaseFactory.getAttachmentDatabase(context).getAttachmentsForMessage(messageId)) {
        ApplicationContext.getInstance(context).getJobManager().add(new AttachmentDownloadJob(context, messageId, attachment.getAttachmentId(), false));
    }
    if (message.getMessage().getExpiresInSeconds() > 0) {
        database.markExpireStarted(messageId, message.getExpirationStartTimestamp());
        ApplicationContext.getInstance(context).getExpiringMessageManager().scheduleDeletion(messageId, true, message.getExpirationStartTimestamp(), message.getMessage().getExpiresInSeconds() * 1000L);
    }
    return threadId;
}
Also used : OutgoingSecureMediaMessage(org.thoughtcrime.securesms.mms.OutgoingSecureMediaMessage) DatabaseAttachment(org.thoughtcrime.securesms.attachments.DatabaseAttachment) Recipient(org.thoughtcrime.securesms.recipients.Recipient) OutgoingMediaMessage(org.thoughtcrime.securesms.mms.OutgoingMediaMessage) MmsDatabase(org.thoughtcrime.securesms.database.MmsDatabase)

Example 47 with DatabaseAttachment

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

the class MessageSender method sendMediaBroadcast.

public static void sendMediaBroadcast(@NonNull Context context, @NonNull List<OutgoingSecureMediaMessage> messages, @NonNull Collection<PreUploadResult> preUploadResults) {
    Log.i(TAG, "Sending media broadcast to " + Stream.of(messages).map(m -> m.getRecipient().getId()).toList());
    Preconditions.checkArgument(messages.size() > 0, "No messages!");
    Preconditions.checkArgument(Stream.of(messages).allMatch(m -> m.getAttachments().isEmpty()), "Messages can't have attachments! They should be pre-uploaded.");
    JobManager jobManager = ApplicationDependencies.getJobManager();
    AttachmentDatabase attachmentDatabase = SignalDatabase.attachments();
    MessageDatabase mmsDatabase = SignalDatabase.mms();
    ThreadDatabase threadDatabase = SignalDatabase.threads();
    List<AttachmentId> preUploadAttachmentIds = Stream.of(preUploadResults).map(PreUploadResult::getAttachmentId).toList();
    List<String> preUploadJobIds = Stream.of(preUploadResults).map(PreUploadResult::getJobIds).flatMap(Stream::of).toList();
    List<Long> messageIds = new ArrayList<>(messages.size());
    List<String> messageDependsOnIds = new ArrayList<>(preUploadJobIds);
    mmsDatabase.beginTransaction();
    try {
        OutgoingSecureMediaMessage primaryMessage = messages.get(0);
        long primaryThreadId = threadDatabase.getOrCreateThreadIdFor(primaryMessage.getRecipient(), primaryMessage.getDistributionType());
        long primaryMessageId = mmsDatabase.insertMessageOutbox(applyUniversalExpireTimerIfNecessary(context, primaryMessage.getRecipient(), primaryMessage, primaryThreadId), primaryThreadId, false, null);
        attachmentDatabase.updateMessageId(preUploadAttachmentIds, primaryMessageId);
        messageIds.add(primaryMessageId);
        if (messages.size() > 0) {
            List<OutgoingSecureMediaMessage> secondaryMessages = messages.subList(1, messages.size());
            List<List<AttachmentId>> attachmentCopies = new ArrayList<>();
            List<DatabaseAttachment> preUploadAttachments = Stream.of(preUploadAttachmentIds).map(attachmentDatabase::getAttachment).toList();
            for (int i = 0; i < preUploadAttachmentIds.size(); i++) {
                attachmentCopies.add(new ArrayList<>(messages.size()));
            }
            for (OutgoingSecureMediaMessage secondaryMessage : secondaryMessages) {
                long allocatedThreadId = threadDatabase.getOrCreateThreadIdFor(secondaryMessage.getRecipient(), secondaryMessage.getDistributionType());
                long messageId = mmsDatabase.insertMessageOutbox(applyUniversalExpireTimerIfNecessary(context, secondaryMessage.getRecipient(), secondaryMessage, allocatedThreadId), allocatedThreadId, false, null);
                List<AttachmentId> attachmentIds = new ArrayList<>(preUploadAttachmentIds.size());
                for (int i = 0; i < preUploadAttachments.size(); i++) {
                    AttachmentId attachmentId = attachmentDatabase.insertAttachmentForPreUpload(preUploadAttachments.get(i)).getAttachmentId();
                    attachmentCopies.get(i).add(attachmentId);
                    attachmentIds.add(attachmentId);
                }
                attachmentDatabase.updateMessageId(attachmentIds, messageId);
                messageIds.add(messageId);
            }
            for (int i = 0; i < attachmentCopies.size(); i++) {
                Job copyJob = new AttachmentCopyJob(preUploadAttachmentIds.get(i), attachmentCopies.get(i));
                jobManager.add(copyJob, preUploadJobIds);
                messageDependsOnIds.add(copyJob.getId());
            }
        }
        for (int i = 0; i < messageIds.size(); i++) {
            long messageId = messageIds.get(i);
            OutgoingSecureMediaMessage message = messages.get(i);
            Recipient recipient = message.getRecipient();
            if (isLocalSelfSend(context, recipient, false)) {
                sendLocalMediaSelf(context, messageId);
            } else if (isGroupPushSend(recipient)) {
                jobManager.add(new PushGroupSendJob(messageId, recipient.getId(), null, true), messageDependsOnIds, recipient.getId().toQueueKey());
            } else {
                jobManager.add(new PushMediaSendJob(messageId, recipient, true), messageDependsOnIds, recipient.getId().toQueueKey());
            }
        }
        onMessageSent();
        mmsDatabase.setTransactionSuccessful();
    } catch (MmsException e) {
        Log.w(TAG, "Failed to send messages.", e);
    } finally {
        mmsDatabase.endTransaction();
    }
}
Also used : SignalStore(org.thoughtcrime.securesms.keyvalue.SignalStore) Arrays(java.util.Arrays) LinkPreview(org.thoughtcrime.securesms.linkpreview.LinkPreview) NonNull(androidx.annotation.NonNull) JobManager(org.thoughtcrime.securesms.jobmanager.JobManager) RecipientUtil(org.thoughtcrime.securesms.recipients.RecipientUtil) AttachmentMarkUploadedJob(org.thoughtcrime.securesms.jobs.AttachmentMarkUploadedJob) MessageRecord(org.thoughtcrime.securesms.database.model.MessageRecord) SmsDatabase(org.thoughtcrime.securesms.database.SmsDatabase) Preconditions(org.whispersystems.libsignal.util.guava.Preconditions) RecipientId(org.thoughtcrime.securesms.recipients.RecipientId) ParcelUtil(org.thoughtcrime.securesms.util.ParcelUtil) ReactionSendJob(org.thoughtcrime.securesms.jobs.ReactionSendJob) Recipient(org.thoughtcrime.securesms.recipients.Recipient) SyncMessageId(org.thoughtcrime.securesms.database.MessageDatabase.SyncMessageId) PushMediaSendJob(org.thoughtcrime.securesms.jobs.PushMediaSendJob) ApplicationDependencies(org.thoughtcrime.securesms.dependencies.ApplicationDependencies) Collection(java.util.Collection) OutgoingSecureMediaMessage(org.thoughtcrime.securesms.mms.OutgoingSecureMediaMessage) ReactionRecord(org.thoughtcrime.securesms.database.model.ReactionRecord) ThreadDatabase(org.thoughtcrime.securesms.database.ThreadDatabase) Log(org.signal.core.util.logging.Log) List(java.util.List) Nullable(androidx.annotation.Nullable) Job(org.thoughtcrime.securesms.jobmanager.Job) ResumableUploadSpecJob(org.thoughtcrime.securesms.jobs.ResumableUploadSpecJob) MessageDatabase(org.thoughtcrime.securesms.database.MessageDatabase) PushGroupSendJob(org.thoughtcrime.securesms.jobs.PushGroupSendJob) NoSuchMessageException(org.thoughtcrime.securesms.database.NoSuchMessageException) Attachment(org.thoughtcrime.securesms.attachments.Attachment) OutgoingMediaMessage(org.thoughtcrime.securesms.mms.OutgoingMediaMessage) AttachmentCompressionJob(org.thoughtcrime.securesms.jobs.AttachmentCompressionJob) Context(android.content.Context) MmsSmsDatabase(org.thoughtcrime.securesms.database.MmsSmsDatabase) SignalDatabase(org.thoughtcrime.securesms.database.SignalDatabase) ProfileKeySendJob(org.thoughtcrime.securesms.jobs.ProfileKeySendJob) Stream(com.annimon.stream.Stream) DirectoryHelper(org.thoughtcrime.securesms.contacts.sync.DirectoryHelper) SignalLocalMetrics(org.thoughtcrime.securesms.util.SignalLocalMetrics) WorkerThread(androidx.annotation.WorkerThread) AttachmentDatabase(org.thoughtcrime.securesms.database.AttachmentDatabase) RecipientDatabase(org.thoughtcrime.securesms.database.RecipientDatabase) Parcel(android.os.Parcel) DatabaseAttachment(org.thoughtcrime.securesms.attachments.DatabaseAttachment) ArrayList(java.util.ArrayList) RemoteDeleteSendJob(org.thoughtcrime.securesms.jobs.RemoteDeleteSendJob) TextSecurePreferences(org.thoughtcrime.securesms.util.TextSecurePreferences) MmsSendJob(org.thoughtcrime.securesms.jobs.MmsSendJob) AttachmentUploadJob(org.thoughtcrime.securesms.jobs.AttachmentUploadJob) PushTextSendJob(org.thoughtcrime.securesms.jobs.PushTextSendJob) EventBus(org.greenrobot.eventbus.EventBus) AttachmentCopyJob(org.thoughtcrime.securesms.jobs.AttachmentCopyJob) LinkedList(java.util.LinkedList) Parcelable(android.os.Parcelable) MessageId(org.thoughtcrime.securesms.database.model.MessageId) Contact(org.thoughtcrime.securesms.contactshare.Contact) MmsException(org.thoughtcrime.securesms.mms.MmsException) IOException(java.io.IOException) Optional(org.whispersystems.libsignal.util.guava.Optional) TimeUnit(java.util.concurrent.TimeUnit) AttachmentId(org.thoughtcrime.securesms.attachments.AttachmentId) SmsSendJob(org.thoughtcrime.securesms.jobs.SmsSendJob) ExpiringMessageManager(org.thoughtcrime.securesms.service.ExpiringMessageManager) SmsMessageRecord(org.thoughtcrime.securesms.database.model.SmsMessageRecord) Collections(java.util.Collections) PushGroupSendJob(org.thoughtcrime.securesms.jobs.PushGroupSendJob) ArrayList(java.util.ArrayList) JobManager(org.thoughtcrime.securesms.jobmanager.JobManager) MmsException(org.thoughtcrime.securesms.mms.MmsException) AttachmentCopyJob(org.thoughtcrime.securesms.jobs.AttachmentCopyJob) List(java.util.List) ArrayList(java.util.ArrayList) LinkedList(java.util.LinkedList) PushMediaSendJob(org.thoughtcrime.securesms.jobs.PushMediaSendJob) AttachmentMarkUploadedJob(org.thoughtcrime.securesms.jobs.AttachmentMarkUploadedJob) ReactionSendJob(org.thoughtcrime.securesms.jobs.ReactionSendJob) PushMediaSendJob(org.thoughtcrime.securesms.jobs.PushMediaSendJob) Job(org.thoughtcrime.securesms.jobmanager.Job) ResumableUploadSpecJob(org.thoughtcrime.securesms.jobs.ResumableUploadSpecJob) PushGroupSendJob(org.thoughtcrime.securesms.jobs.PushGroupSendJob) AttachmentCompressionJob(org.thoughtcrime.securesms.jobs.AttachmentCompressionJob) ProfileKeySendJob(org.thoughtcrime.securesms.jobs.ProfileKeySendJob) RemoteDeleteSendJob(org.thoughtcrime.securesms.jobs.RemoteDeleteSendJob) MmsSendJob(org.thoughtcrime.securesms.jobs.MmsSendJob) AttachmentUploadJob(org.thoughtcrime.securesms.jobs.AttachmentUploadJob) PushTextSendJob(org.thoughtcrime.securesms.jobs.PushTextSendJob) AttachmentCopyJob(org.thoughtcrime.securesms.jobs.AttachmentCopyJob) SmsSendJob(org.thoughtcrime.securesms.jobs.SmsSendJob) MessageDatabase(org.thoughtcrime.securesms.database.MessageDatabase) DatabaseAttachment(org.thoughtcrime.securesms.attachments.DatabaseAttachment) Recipient(org.thoughtcrime.securesms.recipients.Recipient) ThreadDatabase(org.thoughtcrime.securesms.database.ThreadDatabase) AttachmentDatabase(org.thoughtcrime.securesms.database.AttachmentDatabase) AttachmentId(org.thoughtcrime.securesms.attachments.AttachmentId) OutgoingSecureMediaMessage(org.thoughtcrime.securesms.mms.OutgoingSecureMediaMessage)

Example 48 with DatabaseAttachment

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

the class MessageSender method preUploadPushAttachment.

/**
 * @return A result if the attachment was enqueued, or null if it failed to enqueue or shouldn't
 *         be enqueued (like in the case of a local self-send).
 */
@Nullable
public static PreUploadResult preUploadPushAttachment(@NonNull Context context, @NonNull Attachment attachment, @Nullable Recipient recipient) {
    if (isLocalSelfSend(context, recipient, false)) {
        return null;
    }
    Log.i(TAG, "Pre-uploading attachment for " + (recipient != null ? recipient.getId() : "null"));
    try {
        AttachmentDatabase attachmentDatabase = SignalDatabase.attachments();
        DatabaseAttachment databaseAttachment = attachmentDatabase.insertAttachmentForPreUpload(attachment);
        Job compressionJob = AttachmentCompressionJob.fromAttachment(databaseAttachment, false, -1);
        Job resumableUploadSpecJob = new ResumableUploadSpecJob();
        Job uploadJob = new AttachmentUploadJob(databaseAttachment.getAttachmentId());
        ApplicationDependencies.getJobManager().startChain(compressionJob).then(resumableUploadSpecJob).then(uploadJob).enqueue();
        return new PreUploadResult(databaseAttachment.getAttachmentId(), Arrays.asList(compressionJob.getId(), resumableUploadSpecJob.getId(), uploadJob.getId()));
    } catch (MmsException e) {
        Log.w(TAG, "preUploadPushAttachment() - Failed to upload!", e);
        return null;
    }
}
Also used : MmsException(org.thoughtcrime.securesms.mms.MmsException) DatabaseAttachment(org.thoughtcrime.securesms.attachments.DatabaseAttachment) ResumableUploadSpecJob(org.thoughtcrime.securesms.jobs.ResumableUploadSpecJob) AttachmentMarkUploadedJob(org.thoughtcrime.securesms.jobs.AttachmentMarkUploadedJob) ReactionSendJob(org.thoughtcrime.securesms.jobs.ReactionSendJob) PushMediaSendJob(org.thoughtcrime.securesms.jobs.PushMediaSendJob) Job(org.thoughtcrime.securesms.jobmanager.Job) ResumableUploadSpecJob(org.thoughtcrime.securesms.jobs.ResumableUploadSpecJob) PushGroupSendJob(org.thoughtcrime.securesms.jobs.PushGroupSendJob) AttachmentCompressionJob(org.thoughtcrime.securesms.jobs.AttachmentCompressionJob) ProfileKeySendJob(org.thoughtcrime.securesms.jobs.ProfileKeySendJob) RemoteDeleteSendJob(org.thoughtcrime.securesms.jobs.RemoteDeleteSendJob) MmsSendJob(org.thoughtcrime.securesms.jobs.MmsSendJob) AttachmentUploadJob(org.thoughtcrime.securesms.jobs.AttachmentUploadJob) PushTextSendJob(org.thoughtcrime.securesms.jobs.PushTextSendJob) AttachmentCopyJob(org.thoughtcrime.securesms.jobs.AttachmentCopyJob) SmsSendJob(org.thoughtcrime.securesms.jobs.SmsSendJob) AttachmentDatabase(org.thoughtcrime.securesms.database.AttachmentDatabase) AttachmentUploadJob(org.thoughtcrime.securesms.jobs.AttachmentUploadJob) Nullable(androidx.annotation.Nullable)

Example 49 with DatabaseAttachment

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

the class MmsDatabase method getSharedContacts.

private static List<Contact> getSharedContacts(@NonNull Cursor cursor, @NonNull List<DatabaseAttachment> attachments) {
    String serializedContacts = cursor.getString(cursor.getColumnIndexOrThrow(SHARED_CONTACTS));
    if (TextUtils.isEmpty(serializedContacts)) {
        return Collections.emptyList();
    }
    Map<AttachmentId, DatabaseAttachment> attachmentIdMap = new HashMap<>();
    for (DatabaseAttachment attachment : attachments) {
        attachmentIdMap.put(attachment.getAttachmentId(), attachment);
    }
    try {
        List<Contact> contacts = new LinkedList<>();
        JSONArray jsonContacts = new JSONArray(serializedContacts);
        for (int i = 0; i < jsonContacts.length(); i++) {
            Contact contact = Contact.deserialize(jsonContacts.getJSONObject(i).toString());
            if (contact.getAvatar() != null && contact.getAvatar().getAttachmentId() != null) {
                DatabaseAttachment attachment = attachmentIdMap.get(contact.getAvatar().getAttachmentId());
                Avatar updatedAvatar = new Avatar(contact.getAvatar().getAttachmentId(), attachment, contact.getAvatar().isProfile());
                contacts.add(new Contact(contact, updatedAvatar));
            } else {
                contacts.add(contact);
            }
        }
        return contacts;
    } catch (JSONException | IOException e) {
        Log.w(TAG, "Failed to parse shared contacts.", e);
    }
    return Collections.emptyList();
}
Also used : HashMap(java.util.HashMap) DatabaseAttachment(org.thoughtcrime.securesms.attachments.DatabaseAttachment) JSONArray(org.json.JSONArray) JSONException(org.json.JSONException) IOException(java.io.IOException) AttachmentId(org.thoughtcrime.securesms.attachments.AttachmentId) LinkedList(java.util.LinkedList) Avatar(org.thoughtcrime.securesms.contactshare.Contact.Avatar) Contact(org.thoughtcrime.securesms.contactshare.Contact)

Example 50 with DatabaseAttachment

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

the class AttachmentDatabase method insertAttachmentForPreUpload.

@NonNull
public DatabaseAttachment insertAttachmentForPreUpload(@NonNull Attachment attachment) throws MmsException {
    Map<Attachment, AttachmentId> result = insertAttachmentsForMessage(PREUPLOAD_MESSAGE_ID, Collections.singletonList(attachment), Collections.emptyList());
    if (result.values().isEmpty()) {
        throw new MmsException("Bad attachment result!");
    }
    DatabaseAttachment databaseAttachment = getAttachment(result.values().iterator().next());
    if (databaseAttachment == null) {
        throw new MmsException("Failed to retrieve attachment we just inserted!");
    }
    return databaseAttachment;
}
Also used : MmsException(org.thoughtcrime.securesms.mms.MmsException) DatabaseAttachment(org.thoughtcrime.securesms.attachments.DatabaseAttachment) Attachment(org.thoughtcrime.securesms.attachments.Attachment) DatabaseAttachment(org.thoughtcrime.securesms.attachments.DatabaseAttachment) AttachmentId(org.thoughtcrime.securesms.attachments.AttachmentId) NonNull(androidx.annotation.NonNull)

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