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;
}
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();
}
}
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;
}
}
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();
}
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;
}
Aggregations