use of org.thoughtcrime.securesms.mms.MmsException in project Signal-Android by WhisperSystems.
the class MessageContentProcessor method handleSynchronizeSentMessage.
private void handleSynchronizeSentMessage(@NonNull SignalServiceContent content, @NonNull SentTranscriptMessage message, @NonNull Recipient senderRecipient) throws StorageFailedException, BadGroupIdException, IOException, GroupChangeBusyException {
log(String.valueOf(content.getTimestamp()), "Processing sent transcript for message with ID " + message.getTimestamp());
try {
GroupDatabase groupDatabase = SignalDatabase.groups();
if (message.getMessage().isGroupV2Message()) {
GroupId.V2 groupId = GroupId.v2(message.getMessage().getGroupContext().get().getGroupV2().get().getMasterKey());
if (handleGv2PreProcessing(groupId, content, message.getMessage().getGroupContext().get().getGroupV2().get(), senderRecipient)) {
return;
}
}
long threadId = -1;
if (message.isRecipientUpdate()) {
handleGroupRecipientUpdate(message, content.getTimestamp());
} else if (message.getMessage().isEndSession()) {
threadId = handleSynchronizeSentEndSessionMessage(message, content.getTimestamp());
} else if (message.getMessage().isGroupV1Update()) {
Long gv1ThreadId = GroupV1MessageProcessor.process(context, content, message.getMessage(), true);
threadId = gv1ThreadId == null ? -1 : gv1ThreadId;
} else if (message.getMessage().isGroupV2Update()) {
handleSynchronizeSentGv2Update(content, message);
threadId = SignalDatabase.threads().getOrCreateThreadIdFor(getSyncMessageDestination(message));
} else if (Build.VERSION.SDK_INT > 19 && message.getMessage().getGroupCallUpdate().isPresent()) {
handleGroupCallUpdateMessage(content, message.getMessage(), GroupUtil.idFromGroupContext(message.getMessage().getGroupContext()), senderRecipient);
} else if (message.getMessage().isEmptyGroupV2Message()) {
warn(content.getTimestamp(), "Empty GV2 message! Doing nothing.");
} else if (message.getMessage().isExpirationUpdate()) {
threadId = handleSynchronizeSentExpirationUpdate(message);
} else if (message.getMessage().getReaction().isPresent()) {
handleReaction(content, message.getMessage(), senderRecipient);
threadId = SignalDatabase.threads().getOrCreateThreadIdFor(getSyncMessageDestination(message));
} else if (message.getMessage().getRemoteDelete().isPresent()) {
handleRemoteDelete(content, message.getMessage(), senderRecipient);
} else if (message.getMessage().getAttachments().isPresent() || message.getMessage().getQuote().isPresent() || message.getMessage().getPreviews().isPresent() || message.getMessage().getSticker().isPresent() || message.getMessage().isViewOnce() || message.getMessage().getMentions().isPresent()) {
threadId = handleSynchronizeSentMediaMessage(message, content.getTimestamp());
} else {
threadId = handleSynchronizeSentTextMessage(message, content.getTimestamp());
}
if (message.getMessage().getGroupContext().isPresent() && groupDatabase.isUnknownGroup(GroupUtil.idFromGroupContext(message.getMessage().getGroupContext().get()))) {
handleUnknownGroupMessage(content, message.getMessage().getGroupContext().get(), senderRecipient);
}
if (message.getMessage().getProfileKey().isPresent()) {
Recipient recipient = getSyncMessageDestination(message);
if (recipient != null && !recipient.isSystemContact() && !recipient.isProfileSharing()) {
SignalDatabase.recipients().setProfileSharing(recipient.getId(), true);
}
}
if (threadId != -1) {
SignalDatabase.threads().setRead(threadId, true);
ApplicationDependencies.getMessageNotifier().updateNotification(context);
}
if (SignalStore.rateLimit().needsRecaptcha()) {
log(content.getTimestamp(), "Got a sent transcript while in reCAPTCHA mode. Assuming we're good to message again.");
RateLimitUtil.retryAllRateLimitedMessages(context);
}
ApplicationDependencies.getMessageNotifier().setLastDesktopActivityTimestamp(message.getTimestamp());
} catch (MmsException e) {
throw new StorageFailedException(e, content.getSender().getIdentifier(), content.getSenderDevice());
}
}
use of org.thoughtcrime.securesms.mms.MmsException in project Signal-Android by WhisperSystems.
the class GroupV1MessageProcessor method storeMessage.
@Nullable
private static Long storeMessage(@NonNull Context context, @NonNull SignalServiceContent content, @NonNull SignalServiceGroup group, @NonNull GroupContext storage, boolean outgoing) {
if (group.getAvatar().isPresent()) {
ApplicationDependencies.getJobManager().add(new AvatarGroupsV1DownloadJob(GroupId.v1orThrow(group.getGroupId())));
}
try {
if (outgoing) {
MessageDatabase mmsDatabase = SignalDatabase.mms();
RecipientId recipientId = SignalDatabase.recipients().getOrInsertFromGroupId(GroupId.v1orThrow(group.getGroupId()));
Recipient recipient = Recipient.resolved(recipientId);
OutgoingGroupUpdateMessage outgoingMessage = new OutgoingGroupUpdateMessage(recipient, storage, null, content.getTimestamp(), 0, false, null, Collections.emptyList(), Collections.emptyList(), Collections.emptyList());
long threadId = SignalDatabase.threads().getOrCreateThreadIdFor(recipient);
long messageId = mmsDatabase.insertMessageOutbox(outgoingMessage, threadId, false, null);
mmsDatabase.markAsSent(messageId, true);
return threadId;
} else {
MessageDatabase smsDatabase = SignalDatabase.sms();
String body = Base64.encodeBytes(storage.toByteArray());
IncomingTextMessage incoming = new IncomingTextMessage(Recipient.externalHighTrustPush(context, content.getSender()).getId(), content.getSenderDevice(), content.getTimestamp(), content.getServerReceivedTimestamp(), System.currentTimeMillis(), body, Optional.of(GroupId.v1orThrow(group.getGroupId())), 0, content.isNeedsReceipt(), content.getServerUuid());
IncomingGroupUpdateMessage groupMessage = new IncomingGroupUpdateMessage(incoming, storage, body);
Optional<InsertResult> insertResult = smsDatabase.insertMessageInbox(groupMessage);
if (insertResult.isPresent()) {
ApplicationDependencies.getMessageNotifier().updateNotification(context, insertResult.get().getThreadId());
return insertResult.get().getThreadId();
} else {
return null;
}
}
} catch (MmsException e) {
Log.w(TAG, e);
}
return null;
}
use of org.thoughtcrime.securesms.mms.MmsException in project Signal-Android by WhisperSystems.
the class GroupsV1MigrationUtil method handleLeftBehind.
private static void handleLeftBehind(@NonNull Context context, @NonNull GroupId.V1 gv1Id, @NonNull Recipient groupRecipient, long threadId) {
OutgoingMediaMessage leaveMessage = GroupUtil.createGroupV1LeaveMessage(gv1Id, groupRecipient);
try {
long id = SignalDatabase.mms().insertMessageOutbox(leaveMessage, threadId, false, null);
SignalDatabase.mms().markAsSent(id, true);
} catch (MmsException e) {
Log.w(TAG, "Failed to insert group leave message!", e);
}
SignalDatabase.groups().setActive(gv1Id, false);
SignalDatabase.groups().remove(gv1Id, Recipient.self().getId());
}
use of org.thoughtcrime.securesms.mms.MmsException in project Signal-Android by signalapp.
the class MmsDatabase method insertMediaMessage.
private long insertMediaMessage(long threadId, @Nullable String body, @NonNull List<Attachment> attachments, @NonNull List<Attachment> quoteAttachments, @NonNull List<Contact> sharedContacts, @NonNull List<LinkPreview> linkPreviews, @NonNull List<Mention> mentions, @Nullable BodyRangeList messageRanges, @NonNull ContentValues contentValues, @Nullable InsertListener insertListener, boolean updateThread) throws MmsException {
SQLiteDatabase db = databaseHelper.getSignalWritableDatabase();
AttachmentDatabase partsDatabase = SignalDatabase.attachments();
MentionDatabase mentionDatabase = SignalDatabase.mentions();
boolean mentionsSelf = Stream.of(mentions).filter(m -> Recipient.resolved(m.getRecipientId()).isSelf()).findFirst().isPresent();
List<Attachment> allAttachments = new LinkedList<>();
List<Attachment> contactAttachments = Stream.of(sharedContacts).map(Contact::getAvatarAttachment).filter(a -> a != null).toList();
List<Attachment> previewAttachments = Stream.of(linkPreviews).filter(lp -> lp.getThumbnail().isPresent()).map(lp -> lp.getThumbnail().get()).toList();
allAttachments.addAll(attachments);
allAttachments.addAll(contactAttachments);
allAttachments.addAll(previewAttachments);
contentValues.put(BODY, body);
contentValues.put(PART_COUNT, allAttachments.size());
contentValues.put(MENTIONS_SELF, mentionsSelf ? 1 : 0);
if (messageRanges != null) {
contentValues.put(MESSAGE_RANGES, messageRanges.toByteArray());
}
db.beginTransaction();
try {
long messageId = db.insert(TABLE_NAME, null, contentValues);
mentionDatabase.insert(threadId, messageId, mentions);
Map<Attachment, AttachmentId> insertedAttachments = partsDatabase.insertAttachmentsForMessage(messageId, allAttachments, quoteAttachments);
String serializedContacts = getSerializedSharedContacts(insertedAttachments, sharedContacts);
String serializedPreviews = getSerializedLinkPreviews(insertedAttachments, linkPreviews);
if (!TextUtils.isEmpty(serializedContacts)) {
ContentValues contactValues = new ContentValues();
contactValues.put(SHARED_CONTACTS, serializedContacts);
SQLiteDatabase database = databaseHelper.getSignalReadableDatabase();
int rows = database.update(TABLE_NAME, contactValues, ID + " = ?", new String[] { String.valueOf(messageId) });
if (rows <= 0) {
Log.w(TAG, "Failed to update message with shared contact data.");
}
}
if (!TextUtils.isEmpty(serializedPreviews)) {
ContentValues contactValues = new ContentValues();
contactValues.put(LINK_PREVIEWS, serializedPreviews);
SQLiteDatabase database = databaseHelper.getSignalReadableDatabase();
int rows = database.update(TABLE_NAME, contactValues, ID + " = ?", new String[] { String.valueOf(messageId) });
if (rows <= 0) {
Log.w(TAG, "Failed to update message with link preview data.");
}
}
db.setTransactionSuccessful();
return messageId;
} finally {
db.endTransaction();
if (insertListener != null) {
insertListener.onComplete();
}
long contentValuesThreadId = contentValues.getAsLong(THREAD_ID);
if (updateThread) {
SignalDatabase.threads().setLastScrolled(contentValuesThreadId, 0);
SignalDatabase.threads().update(threadId, true);
}
}
}
use of org.thoughtcrime.securesms.mms.MmsException in project Signal-Android by signalapp.
the class AttachmentDatabase method updateAttachmentData.
/**
* @param onlyModifyThisAttachment If false and more than one attachment shares this file, they will all be updated.
* If true, then guarantees not to affect other attachments.
*/
public void updateAttachmentData(@NonNull DatabaseAttachment databaseAttachment, @NonNull MediaStream mediaStream, boolean onlyModifyThisAttachment) throws MmsException, IOException {
SQLiteDatabase database = databaseHelper.getSignalWritableDatabase();
DataInfo oldDataInfo = getAttachmentDataFileInfo(databaseAttachment.getAttachmentId(), DATA);
if (oldDataInfo == null) {
throw new MmsException("No attachment data found!");
}
File destination = oldDataInfo.file;
if (onlyModifyThisAttachment) {
if (fileReferencedByMoreThanOneAttachment(destination)) {
Log.i(TAG, "Creating a new file as this one is used by more than one attachment");
destination = newFile();
}
}
DataInfo dataInfo = setAttachmentData(destination, mediaStream.getStream(), databaseAttachment.getAttachmentId());
ContentValues contentValues = new ContentValues();
contentValues.put(SIZE, dataInfo.length);
contentValues.put(CONTENT_TYPE, mediaStream.getMimeType());
contentValues.put(WIDTH, mediaStream.getWidth());
contentValues.put(HEIGHT, mediaStream.getHeight());
contentValues.put(DATA, dataInfo.file.getAbsolutePath());
contentValues.put(DATA_RANDOM, dataInfo.random);
contentValues.put(DATA_HASH, dataInfo.hash);
int updateCount = updateAttachmentAndMatchingHashes(database, databaseAttachment.getAttachmentId(), oldDataInfo.hash, contentValues);
Log.i(TAG, "[updateAttachmentData] Updated " + updateCount + " rows.");
}
Aggregations