Search in sources :

Example 16 with MmsException

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());
    }
}
Also used : MmsException(org.thoughtcrime.securesms.mms.MmsException) GroupDatabase(org.thoughtcrime.securesms.database.GroupDatabase) Recipient(org.thoughtcrime.securesms.recipients.Recipient) GroupId(org.thoughtcrime.securesms.groups.GroupId)

Example 17 with MmsException

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;
}
Also used : InsertResult(org.thoughtcrime.securesms.database.MessageDatabase.InsertResult) AvatarGroupsV1DownloadJob(org.thoughtcrime.securesms.jobs.AvatarGroupsV1DownloadJob) MessageDatabase(org.thoughtcrime.securesms.database.MessageDatabase) MmsException(org.thoughtcrime.securesms.mms.MmsException) RecipientId(org.thoughtcrime.securesms.recipients.RecipientId) IncomingGroupUpdateMessage(org.thoughtcrime.securesms.sms.IncomingGroupUpdateMessage) IncomingTextMessage(org.thoughtcrime.securesms.sms.IncomingTextMessage) Recipient(org.thoughtcrime.securesms.recipients.Recipient) ByteString(com.google.protobuf.ByteString) OutgoingGroupUpdateMessage(org.thoughtcrime.securesms.mms.OutgoingGroupUpdateMessage) Nullable(androidx.annotation.Nullable)

Example 18 with MmsException

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());
}
Also used : MmsException(org.thoughtcrime.securesms.mms.MmsException) OutgoingMediaMessage(org.thoughtcrime.securesms.mms.OutgoingMediaMessage)

Example 19 with MmsException

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);
        }
    }
}
Also used : SignalStore(org.thoughtcrime.securesms.keyvalue.SignalStore) SlideDeck(org.thoughtcrime.securesms.mms.SlideDeck) GroupMigrationMembershipChange(org.thoughtcrime.securesms.groups.GroupMigrationMembershipChange) LinkPreview(org.thoughtcrime.securesms.linkpreview.LinkPreview) NonNull(androidx.annotation.NonNull) Avatar(org.thoughtcrime.securesms.contactshare.Contact.Avatar) MessageGroupContext(org.thoughtcrime.securesms.mms.MessageGroupContext) Mention(org.thoughtcrime.securesms.database.model.Mention) MessageRecord(org.thoughtcrime.securesms.database.model.MessageRecord) SecureRandom(java.security.SecureRandom) JSONException(org.json.JSONException) JsonUtils(org.thoughtcrime.securesms.util.JsonUtils) JSONObject(org.json.JSONObject) RecipientId(org.thoughtcrime.securesms.recipients.RecipientId) BodyRangeList(org.thoughtcrime.securesms.database.model.databaseprotos.BodyRangeList) SqlUtil(org.thoughtcrime.securesms.util.SqlUtil) IdentityKeyMismatchSet(org.thoughtcrime.securesms.database.documents.IdentityKeyMismatchSet) Map(java.util.Map) ViewOnceUtil(org.thoughtcrime.securesms.revealable.ViewOnceUtil) Recipient(org.thoughtcrime.securesms.recipients.Recipient) OutgoingTextMessage(org.thoughtcrime.securesms.sms.OutgoingTextMessage) OutgoingGroupUpdateMessage(org.thoughtcrime.securesms.mms.OutgoingGroupUpdateMessage) InvalidProtocolBufferException(com.google.protobuf.InvalidProtocolBufferException) NotificationInd(com.google.android.mms.pdu_alt.NotificationInd) ACI(org.whispersystems.signalservice.api.push.ACI) ApplicationDependencies(org.thoughtcrime.securesms.dependencies.ApplicationDependencies) Collection(java.util.Collection) OutgoingSecureMediaMessage(org.thoughtcrime.securesms.mms.OutgoingSecureMediaMessage) Set(java.util.Set) UUID(java.util.UUID) OutgoingExpirationUpdateMessage(org.thoughtcrime.securesms.mms.OutgoingExpirationUpdateMessage) Log(org.signal.core.util.logging.Log) NetworkFailureSet(org.thoughtcrime.securesms.database.documents.NetworkFailureSet) List(java.util.List) Nullable(androidx.annotation.Nullable) ContentValues(android.content.ContentValues) IncomingTextMessage(org.thoughtcrime.securesms.sms.IncomingTextMessage) Attachment(org.thoughtcrime.securesms.attachments.Attachment) OutgoingMediaMessage(org.thoughtcrime.securesms.mms.OutgoingMediaMessage) MediaUtil(org.thoughtcrime.securesms.util.MediaUtil) Context(android.content.Context) Stream(com.annimon.stream.Stream) Util(org.thoughtcrime.securesms.util.Util) HashMap(java.util.HashMap) SQLiteStatement(net.zetetic.database.sqlcipher.SQLiteStatement) DatabaseAttachment(org.thoughtcrime.securesms.attachments.DatabaseAttachment) ArrayList(java.util.ArrayList) TextSecurePreferences(org.thoughtcrime.securesms.util.TextSecurePreferences) HashSet(java.util.HashSet) Pair(org.whispersystems.libsignal.util.Pair) MmsNotificationAttachment(org.thoughtcrime.securesms.attachments.MmsNotificationAttachment) NotificationMmsMessageRecord(org.thoughtcrime.securesms.database.model.NotificationMmsMessageRecord) QuoteModel(org.thoughtcrime.securesms.mms.QuoteModel) MediaMmsMessageRecord(org.thoughtcrime.securesms.database.model.MediaMmsMessageRecord) LinkedList(java.util.LinkedList) PduHeaders(com.google.android.mms.pdu_alt.PduHeaders) Cursor(android.database.Cursor) MessageId(org.thoughtcrime.securesms.database.model.MessageId) Collectors(com.annimon.stream.Collectors) Contact(org.thoughtcrime.securesms.contactshare.Contact) IdentityKeyMismatch(org.thoughtcrime.securesms.database.documents.IdentityKeyMismatch) MmsException(org.thoughtcrime.securesms.mms.MmsException) TextUtils(android.text.TextUtils) IOException(java.io.IOException) Quote(org.thoughtcrime.securesms.database.model.Quote) Optional(org.whispersystems.libsignal.util.guava.Optional) CursorUtil(org.thoughtcrime.securesms.util.CursorUtil) ViewOnceExpirationInfo(org.thoughtcrime.securesms.revealable.ViewOnceExpirationInfo) AttachmentId(org.thoughtcrime.securesms.attachments.AttachmentId) NetworkFailure(org.thoughtcrime.securesms.database.documents.NetworkFailure) TrimThreadJob(org.thoughtcrime.securesms.jobs.TrimThreadJob) SmsMessageRecord(org.thoughtcrime.securesms.database.model.SmsMessageRecord) Collections(java.util.Collections) JSONArray(org.json.JSONArray) IncomingMediaMessage(org.thoughtcrime.securesms.mms.IncomingMediaMessage) ContentValues(android.content.ContentValues) Attachment(org.thoughtcrime.securesms.attachments.Attachment) DatabaseAttachment(org.thoughtcrime.securesms.attachments.DatabaseAttachment) MmsNotificationAttachment(org.thoughtcrime.securesms.attachments.MmsNotificationAttachment) LinkedList(java.util.LinkedList) AttachmentId(org.thoughtcrime.securesms.attachments.AttachmentId) Contact(org.thoughtcrime.securesms.contactshare.Contact)

Example 20 with MmsException

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.");
}
Also used : ContentValues(android.content.ContentValues) MmsException(org.thoughtcrime.securesms.mms.MmsException) File(java.io.File)

Aggregations

MmsException (org.thoughtcrime.securesms.mms.MmsException)61 IOException (java.io.IOException)26 Recipient (org.thoughtcrime.securesms.recipients.Recipient)26 MessageDatabase (org.thoughtcrime.securesms.database.MessageDatabase)24 NonNull (androidx.annotation.NonNull)20 DatabaseAttachment (org.thoughtcrime.securesms.attachments.DatabaseAttachment)20 OutgoingMediaMessage (org.thoughtcrime.securesms.mms.OutgoingMediaMessage)19 Nullable (androidx.annotation.Nullable)18 Attachment (org.thoughtcrime.securesms.attachments.Attachment)18 AttachmentDatabase (org.thoughtcrime.securesms.database.AttachmentDatabase)15 List (java.util.List)14 MessageId (org.thoughtcrime.securesms.database.model.MessageId)14 Context (android.content.Context)12 WorkerThread (androidx.annotation.WorkerThread)12 Stream (com.annimon.stream.Stream)12 LinkedList (java.util.LinkedList)12 Log (org.signal.core.util.logging.Log)12 AttachmentId (org.thoughtcrime.securesms.attachments.AttachmentId)12 NoSuchMessageException (org.thoughtcrime.securesms.database.NoSuchMessageException)12 ApplicationDependencies (org.thoughtcrime.securesms.dependencies.ApplicationDependencies)12