Search in sources :

Example 81 with MessageId

use of org.thoughtcrime.securesms.database.model.MessageId in project Signal-Android by signalapp.

the class SmsDatabase method incrementReceiptCount.

@Override
@NonNull
public Set<MessageUpdate> incrementReceiptCount(SyncMessageId messageId, long timestamp, @NonNull ReceiptType receiptType) {
    if (receiptType == ReceiptType.VIEWED) {
        return Collections.emptySet();
    }
    SQLiteDatabase database = databaseHelper.getSignalWritableDatabase();
    Set<MessageUpdate> messageUpdates = new HashSet<>();
    try (Cursor cursor = database.query(TABLE_NAME, new String[] { ID, THREAD_ID, RECIPIENT_ID, TYPE, DELIVERY_RECEIPT_COUNT, READ_RECEIPT_COUNT, RECEIPT_TIMESTAMP }, DATE_SENT + " = ?", new String[] { String.valueOf(messageId.getTimetamp()) }, null, null, null, null)) {
        while (cursor.moveToNext()) {
            if (Types.isOutgoingMessageType(CursorUtil.requireLong(cursor, TYPE))) {
                RecipientId theirRecipientId = messageId.getRecipientId();
                RecipientId outRecipientId = RecipientId.from(CursorUtil.requireLong(cursor, RECIPIENT_ID));
                if (outRecipientId.equals(theirRecipientId)) {
                    long id = CursorUtil.requireLong(cursor, ID);
                    long threadId = CursorUtil.requireLong(cursor, THREAD_ID);
                    String columnName = receiptType.getColumnName();
                    boolean isFirstIncrement = CursorUtil.requireLong(cursor, columnName) == 0;
                    long savedTimestamp = CursorUtil.requireLong(cursor, RECEIPT_TIMESTAMP);
                    long updatedTimestamp = isFirstIncrement ? Math.max(savedTimestamp, timestamp) : savedTimestamp;
                    database.execSQL("UPDATE " + TABLE_NAME + " SET " + columnName + " = " + columnName + " + 1, " + RECEIPT_TIMESTAMP + " = ? WHERE " + ID + " = ?", SqlUtil.buildArgs(updatedTimestamp, id));
                    messageUpdates.add(new MessageUpdate(threadId, new MessageId(id, false)));
                }
            }
        }
        if (messageUpdates.isEmpty() && receiptType == ReceiptType.DELIVERY) {
            earlyDeliveryReceiptCache.increment(messageId.getTimetamp(), messageId.getRecipientId(), timestamp);
        }
        return messageUpdates;
    }
}
Also used : RecipientId(org.thoughtcrime.securesms.recipients.RecipientId) Cursor(android.database.Cursor) HashSet(java.util.HashSet) MessageId(org.thoughtcrime.securesms.database.model.MessageId) NonNull(androidx.annotation.NonNull)

Example 82 with MessageId

use of org.thoughtcrime.securesms.database.model.MessageId in project Signal-Android by signalapp.

the class MmsDatabase method setMessagesRead.

private List<MarkedMessageInfo> setMessagesRead(String where, String[] arguments) {
    SQLiteDatabase database = databaseHelper.getSignalWritableDatabase();
    List<MarkedMessageInfo> result = new LinkedList<>();
    Cursor cursor = null;
    RecipientId releaseChannelId = SignalStore.releaseChannelValues().getReleaseChannelRecipientId();
    database.beginTransaction();
    try {
        cursor = database.query(TABLE_NAME, new String[] { ID, RECIPIENT_ID, DATE_SENT, MESSAGE_BOX, EXPIRES_IN, EXPIRE_STARTED, THREAD_ID }, where, arguments, null, null, null);
        while (cursor != null && cursor.moveToNext()) {
            if (Types.isSecureType(CursorUtil.requireLong(cursor, MESSAGE_BOX))) {
                long threadId = CursorUtil.requireLong(cursor, THREAD_ID);
                RecipientId recipientId = RecipientId.from(CursorUtil.requireLong(cursor, RECIPIENT_ID));
                long dateSent = CursorUtil.requireLong(cursor, DATE_SENT);
                long messageId = CursorUtil.requireLong(cursor, ID);
                long expiresIn = CursorUtil.requireLong(cursor, EXPIRES_IN);
                long expireStarted = CursorUtil.requireLong(cursor, EXPIRE_STARTED);
                SyncMessageId syncMessageId = new SyncMessageId(recipientId, dateSent);
                ExpirationInfo expirationInfo = new ExpirationInfo(messageId, expiresIn, expireStarted, true);
                if (!recipientId.equals(releaseChannelId)) {
                    result.add(new MarkedMessageInfo(threadId, syncMessageId, new MessageId(messageId, true), expirationInfo));
                }
            }
        }
        ContentValues contentValues = new ContentValues();
        contentValues.put(READ, 1);
        contentValues.put(REACTIONS_UNREAD, 0);
        contentValues.put(REACTIONS_LAST_SEEN, System.currentTimeMillis());
        database.update(TABLE_NAME, contentValues, where, arguments);
        database.setTransactionSuccessful();
    } finally {
        if (cursor != null)
            cursor.close();
        database.endTransaction();
    }
    return result;
}
Also used : ContentValues(android.content.ContentValues) ViewOnceExpirationInfo(org.thoughtcrime.securesms.revealable.ViewOnceExpirationInfo) RecipientId(org.thoughtcrime.securesms.recipients.RecipientId) Cursor(android.database.Cursor) LinkedList(java.util.LinkedList) MessageId(org.thoughtcrime.securesms.database.model.MessageId)

Example 83 with MessageId

use of org.thoughtcrime.securesms.database.model.MessageId in project Signal-Android by signalapp.

the class MessageContentProcessor method handleTextMessage.

@Nullable
private MessageId handleTextMessage(@NonNull SignalServiceContent content, @NonNull SignalServiceDataMessage message, @NonNull Optional<Long> smsMessageId, @NonNull Optional<GroupId> groupId, @NonNull Recipient senderRecipient, @NonNull Recipient threadRecipient, long receivedTime) throws StorageFailedException {
    log(message.getTimestamp(), "Text message.");
    MessageDatabase database = SignalDatabase.sms();
    String body = message.getBody().isPresent() ? message.getBody().get() : "";
    if (message.getExpiresInSeconds() != threadRecipient.getExpiresInSeconds()) {
        handleExpirationUpdate(content, message, Optional.absent(), groupId, senderRecipient, threadRecipient, receivedTime);
    }
    Optional<InsertResult> insertResult;
    if (smsMessageId.isPresent() && !message.getGroupContext().isPresent()) {
        insertResult = Optional.of(database.updateBundleMessageBody(smsMessageId.get(), body));
    } else {
        notifyTypingStoppedFromIncomingMessage(senderRecipient, threadRecipient, content.getSenderDevice());
        IncomingTextMessage textMessage = new IncomingTextMessage(senderRecipient.getId(), content.getSenderDevice(), message.getTimestamp(), content.getServerReceivedTimestamp(), receivedTime, body, groupId, TimeUnit.SECONDS.toMillis(message.getExpiresInSeconds()), content.isNeedsReceipt(), content.getServerUuid());
        textMessage = new IncomingEncryptedMessage(textMessage, body);
        insertResult = database.insertMessageInbox(textMessage);
        if (smsMessageId.isPresent())
            database.deleteMessage(smsMessageId.get());
    }
    if (insertResult.isPresent()) {
        ApplicationDependencies.getMessageNotifier().updateNotification(context, insertResult.get().getThreadId());
        return new MessageId(insertResult.get().getMessageId(), false);
    } else {
        return null;
    }
}
Also used : InsertResult(org.thoughtcrime.securesms.database.MessageDatabase.InsertResult) IncomingEncryptedMessage(org.thoughtcrime.securesms.sms.IncomingEncryptedMessage) MessageDatabase(org.thoughtcrime.securesms.database.MessageDatabase) IncomingTextMessage(org.thoughtcrime.securesms.sms.IncomingTextMessage) MessageId(org.thoughtcrime.securesms.database.model.MessageId) SyncMessageId(org.thoughtcrime.securesms.database.MessageDatabase.SyncMessageId) Nullable(androidx.annotation.Nullable)

Example 84 with MessageId

use of org.thoughtcrime.securesms.database.model.MessageId in project Signal-Android by signalapp.

the class GroupSendUtil method sendMessage.

/**
 * Handles all of the logic of sending to a group. Will do sender key sends and legacy 1:1 sends as-needed, and give you back a list of
 * {@link SendMessageResult}s just like we're used to.
 *
 * @param groupId The groupId of the group you're sending to, or null if you're sending to a collection of recipients not joined by a group.
 * @param isRecipientUpdate True if you've already sent this message to some recipients in the past, otherwise false.
 */
@WorkerThread
private static List<SendMessageResult> sendMessage(@NonNull Context context, @Nullable GroupId.V2 groupId, @Nullable MessageId relatedMessageId, @NonNull List<Recipient> allTargets, boolean isRecipientUpdate, @NonNull SendOperation sendOperation, @Nullable CancelationSignal cancelationSignal) throws IOException, UntrustedIdentityException {
    Log.i(TAG, "Starting group send. GroupId: " + (groupId != null ? groupId.toString() : "none") + ", RelatedMessageId: " + (relatedMessageId != null ? relatedMessageId.toString() : "none") + ", Targets: " + allTargets.size() + ", RecipientUpdate: " + isRecipientUpdate + ", Operation: " + sendOperation.getClass().getSimpleName());
    Set<Recipient> unregisteredTargets = allTargets.stream().filter(Recipient::isUnregistered).collect(Collectors.toSet());
    List<Recipient> registeredTargets = allTargets.stream().filter(r -> !unregisteredTargets.contains(r)).collect(Collectors.toList());
    RecipientData recipients = new RecipientData(context, registeredTargets);
    Optional<GroupRecord> groupRecord = groupId != null ? SignalDatabase.groups().getGroup(groupId) : Optional.absent();
    List<Recipient> senderKeyTargets = new LinkedList<>();
    List<Recipient> legacyTargets = new LinkedList<>();
    for (Recipient recipient : registeredTargets) {
        Optional<UnidentifiedAccessPair> access = recipients.getAccessPair(recipient.getId());
        boolean validMembership = groupRecord.isPresent() && groupRecord.get().getMembers().contains(recipient.getId());
        if (recipient.getSenderKeyCapability() == Recipient.Capability.SUPPORTED && recipient.hasServiceId() && access.isPresent() && access.get().getTargetUnidentifiedAccess().isPresent() && validMembership) {
            senderKeyTargets.add(recipient);
        } else {
            legacyTargets.add(recipient);
        }
    }
    if (groupId == null) {
        Log.i(TAG, "Recipients not in a group. Using legacy.");
        legacyTargets.addAll(senderKeyTargets);
        senderKeyTargets.clear();
    } else if (Recipient.self().getSenderKeyCapability() != Recipient.Capability.SUPPORTED) {
        Log.i(TAG, "All of our devices do not support sender key. Using legacy.");
        legacyTargets.addAll(senderKeyTargets);
        senderKeyTargets.clear();
    } else if (SignalStore.internalValues().removeSenderKeyMinimum()) {
        Log.i(TAG, "Sender key minimum removed. Using for " + senderKeyTargets.size() + " recipients.");
    } else if (senderKeyTargets.size() < 2) {
        Log.i(TAG, "Too few sender-key-capable users (" + senderKeyTargets.size() + "). Doing all legacy sends.");
        legacyTargets.addAll(senderKeyTargets);
        senderKeyTargets.clear();
    } else {
        Log.i(TAG, "Can use sender key for " + senderKeyTargets.size() + "/" + allTargets.size() + " recipients.");
    }
    if (relatedMessageId != null) {
        SignalLocalMetrics.GroupMessageSend.onSenderKeyStarted(relatedMessageId.getId());
    }
    List<SendMessageResult> allResults = new ArrayList<>(allTargets.size());
    SignalServiceMessageSender messageSender = ApplicationDependencies.getSignalServiceMessageSender();
    if (senderKeyTargets.size() > 0 && groupId != null) {
        DistributionId distributionId = SignalDatabase.groups().getOrCreateDistributionId(groupId);
        long keyCreateTime = SenderKeyUtil.getCreateTimeForOurKey(context, distributionId);
        long keyAge = System.currentTimeMillis() - keyCreateTime;
        if (keyCreateTime != -1 && keyAge > FeatureFlags.senderKeyMaxAge()) {
            Log.w(TAG, "DistributionId " + distributionId + " was created at " + keyCreateTime + " and is " + (keyAge) + " ms old (~" + TimeUnit.MILLISECONDS.toDays(keyAge) + " days). Rotating.");
            SenderKeyUtil.rotateOurKey(context, distributionId);
        }
        try {
            List<SignalServiceAddress> targets = senderKeyTargets.stream().map(r -> recipients.getAddress(r.getId())).collect(Collectors.toList());
            List<UnidentifiedAccess> access = senderKeyTargets.stream().map(r -> recipients.requireAccess(r.getId())).collect(Collectors.toList());
            List<SendMessageResult> results = sendOperation.sendWithSenderKey(messageSender, distributionId, targets, access, isRecipientUpdate);
            allResults.addAll(results);
            int successCount = (int) results.stream().filter(SendMessageResult::isSuccess).count();
            Log.d(TAG, "Successfully sent using sender key to " + successCount + "/" + targets.size() + " sender key targets.");
            if (sendOperation.shouldIncludeInMessageLog()) {
                SignalDatabase.messageLog().insertIfPossible(sendOperation.getSentTimestamp(), senderKeyTargets, results, sendOperation.getContentHint(), sendOperation.getRelatedMessageId());
            }
            if (relatedMessageId != null) {
                SignalLocalMetrics.GroupMessageSend.onSenderKeyMslInserted(relatedMessageId.getId());
            }
        } catch (InvalidUnidentifiedAccessHeaderException e) {
            Log.w(TAG, "Someone had a bad UD header. Falling back to legacy sends.", e);
            legacyTargets.addAll(senderKeyTargets);
        } catch (NoSessionException e) {
            Log.w(TAG, "No session. Falling back to legacy sends.", e);
            legacyTargets.addAll(senderKeyTargets);
        } catch (InvalidKeyException e) {
            Log.w(TAG, "Invalid key. Falling back to legacy sends.", e);
            legacyTargets.addAll(senderKeyTargets);
        } catch (InvalidRegistrationIdException e) {
            Log.w(TAG, "Invalid registrationId. Falling back to legacy sends.", e);
            legacyTargets.addAll(senderKeyTargets);
        } catch (NotFoundException e) {
            Log.w(TAG, "Someone was unregistered. Falling back to legacy sends.", e);
            legacyTargets.addAll(senderKeyTargets);
        }
    } else if (relatedMessageId != null) {
        SignalLocalMetrics.GroupMessageSend.onSenderKeyShared(relatedMessageId.getId());
        SignalLocalMetrics.GroupMessageSend.onSenderKeyEncrypted(relatedMessageId.getId());
        SignalLocalMetrics.GroupMessageSend.onSenderKeyMessageSent(relatedMessageId.getId());
        SignalLocalMetrics.GroupMessageSend.onSenderKeySyncSent(relatedMessageId.getId());
        SignalLocalMetrics.GroupMessageSend.onSenderKeyMslInserted(relatedMessageId.getId());
    }
    if (cancelationSignal != null && cancelationSignal.isCanceled()) {
        throw new CancelationException();
    }
    boolean onlyTargetIsSelfWithLinkedDevice = legacyTargets.isEmpty() && senderKeyTargets.isEmpty() && TextSecurePreferences.isMultiDevice(context);
    if (legacyTargets.size() > 0 || onlyTargetIsSelfWithLinkedDevice) {
        if (legacyTargets.size() > 0) {
            Log.i(TAG, "Need to do " + legacyTargets.size() + " legacy sends.");
        } else {
            Log.i(TAG, "Need to do a legacy send to send a sync message for a group of only ourselves.");
        }
        List<SignalServiceAddress> targets = legacyTargets.stream().map(r -> recipients.getAddress(r.getId())).collect(Collectors.toList());
        List<Optional<UnidentifiedAccessPair>> access = legacyTargets.stream().map(r -> recipients.getAccessPair(r.getId())).collect(Collectors.toList());
        boolean recipientUpdate = isRecipientUpdate || allResults.size() > 0;
        final MessageSendLogDatabase messageLogDatabase = SignalDatabase.messageLog();
        final AtomicLong entryId = new AtomicLong(-1);
        final boolean includeInMessageLog = sendOperation.shouldIncludeInMessageLog();
        List<SendMessageResult> results = sendOperation.sendLegacy(messageSender, targets, access, recipientUpdate, result -> {
            if (!includeInMessageLog) {
                return;
            }
            synchronized (entryId) {
                if (entryId.get() == -1) {
                    entryId.set(messageLogDatabase.insertIfPossible(recipients.requireRecipientId(result.getAddress()), sendOperation.getSentTimestamp(), result, sendOperation.getContentHint(), sendOperation.getRelatedMessageId()));
                } else {
                    messageLogDatabase.addRecipientToExistingEntryIfPossible(entryId.get(), recipients.requireRecipientId(result.getAddress()), result);
                }
            }
        }, cancelationSignal);
        allResults.addAll(results);
        int successCount = (int) results.stream().filter(SendMessageResult::isSuccess).count();
        Log.d(TAG, "Successfully sent using 1:1 to " + successCount + "/" + targets.size() + " legacy targets.");
    } else if (relatedMessageId != null) {
        SignalLocalMetrics.GroupMessageSend.onLegacyMessageSent(relatedMessageId.getId());
        SignalLocalMetrics.GroupMessageSend.onLegacySyncFinished(relatedMessageId.getId());
    }
    if (unregisteredTargets.size() > 0) {
        Log.w(TAG, "There are " + unregisteredTargets.size() + " unregistered targets. Including failure results.");
        List<SendMessageResult> unregisteredResults = unregisteredTargets.stream().filter(Recipient::hasServiceId).map(t -> SendMessageResult.unregisteredFailure(new SignalServiceAddress(t.requireServiceId(), t.getE164().orNull()))).collect(Collectors.toList());
        if (unregisteredResults.size() < unregisteredTargets.size()) {
            Log.w(TAG, "There are " + (unregisteredTargets.size() - unregisteredResults.size()) + " targets that have no UUID! Cannot report a failure for them.");
        }
        allResults.addAll(unregisteredResults);
    }
    return allResults;
}
Also used : SignalStore(org.thoughtcrime.securesms.keyvalue.SignalStore) SignalServiceDataMessage(org.whispersystems.signalservice.api.messages.SignalServiceDataMessage) SendMessageResult(org.whispersystems.signalservice.api.messages.SendMessageResult) NonNull(androidx.annotation.NonNull) RecipientUtil(org.thoughtcrime.securesms.recipients.RecipientUtil) SignalServiceAddress(org.whispersystems.signalservice.api.push.SignalServiceAddress) NotFoundException(org.whispersystems.signalservice.api.push.exceptions.NotFoundException) SenderKeyUtil(org.thoughtcrime.securesms.crypto.SenderKeyUtil) RecipientId(org.thoughtcrime.securesms.recipients.RecipientId) Map(java.util.Map) Recipient(org.thoughtcrime.securesms.recipients.Recipient) LegacyGroupEvents(org.whispersystems.signalservice.api.SignalServiceMessageSender.LegacyGroupEvents) PartialSendCompleteListener(org.whispersystems.signalservice.internal.push.http.PartialSendCompleteListener) ApplicationDependencies(org.thoughtcrime.securesms.dependencies.ApplicationDependencies) InvalidUnidentifiedAccessHeaderException(org.whispersystems.signalservice.internal.push.exceptions.InvalidUnidentifiedAccessHeaderException) Set(java.util.Set) UnidentifiedAccessUtil(org.thoughtcrime.securesms.crypto.UnidentifiedAccessUtil) Collectors(java.util.stream.Collectors) Objects(java.util.Objects) Log(org.signal.core.util.logging.Log) FeatureFlags(org.thoughtcrime.securesms.util.FeatureFlags) List(java.util.List) Nullable(androidx.annotation.Nullable) GroupId(org.thoughtcrime.securesms.groups.GroupId) NoSessionException(org.whispersystems.libsignal.NoSessionException) CancelationException(org.whispersystems.signalservice.api.CancelationException) Context(android.content.Context) RecipientAccessList(org.thoughtcrime.securesms.util.RecipientAccessList) SignalDatabase(org.thoughtcrime.securesms.database.SignalDatabase) ContentHint(org.whispersystems.signalservice.api.crypto.ContentHint) SignalServiceTypingMessage(org.whispersystems.signalservice.api.messages.SignalServiceTypingMessage) SignalLocalMetrics(org.thoughtcrime.securesms.util.SignalLocalMetrics) WorkerThread(androidx.annotation.WorkerThread) GroupRecord(org.thoughtcrime.securesms.database.GroupDatabase.GroupRecord) SenderKeyGroupEvents(org.whispersystems.signalservice.api.SignalServiceMessageSender.SenderKeyGroupEvents) CancelationSignal(org.whispersystems.signalservice.internal.push.http.CancelationSignal) HashMap(java.util.HashMap) InvalidRegistrationIdException(org.whispersystems.libsignal.InvalidRegistrationIdException) InvalidKeyException(org.whispersystems.libsignal.InvalidKeyException) UnidentifiedAccessPair(org.whispersystems.signalservice.api.crypto.UnidentifiedAccessPair) ArrayList(java.util.ArrayList) TextSecurePreferences(org.thoughtcrime.securesms.util.TextSecurePreferences) UnidentifiedAccess(org.whispersystems.signalservice.api.crypto.UnidentifiedAccess) SignalServiceCallMessage(org.whispersystems.signalservice.api.messages.calls.SignalServiceCallMessage) MessageSendLogDatabase(org.thoughtcrime.securesms.database.MessageSendLogDatabase) LinkedList(java.util.LinkedList) DistributionId(org.whispersystems.signalservice.api.push.DistributionId) SignalServiceMessageSender(org.whispersystems.signalservice.api.SignalServiceMessageSender) MessageId(org.thoughtcrime.securesms.database.model.MessageId) Iterator(java.util.Iterator) IOException(java.io.IOException) Optional(org.whispersystems.libsignal.util.guava.Optional) TimeUnit(java.util.concurrent.TimeUnit) AtomicLong(java.util.concurrent.atomic.AtomicLong) UntrustedIdentityException(org.whispersystems.signalservice.api.crypto.UntrustedIdentityException) Collections(java.util.Collections) ArrayList(java.util.ArrayList) SignalServiceMessageSender(org.whispersystems.signalservice.api.SignalServiceMessageSender) NotFoundException(org.whispersystems.signalservice.api.push.exceptions.NotFoundException) MessageSendLogDatabase(org.thoughtcrime.securesms.database.MessageSendLogDatabase) GroupRecord(org.thoughtcrime.securesms.database.GroupDatabase.GroupRecord) NoSessionException(org.whispersystems.libsignal.NoSessionException) CancelationException(org.whispersystems.signalservice.api.CancelationException) SignalServiceAddress(org.whispersystems.signalservice.api.push.SignalServiceAddress) Optional(org.whispersystems.libsignal.util.guava.Optional) InvalidRegistrationIdException(org.whispersystems.libsignal.InvalidRegistrationIdException) Recipient(org.thoughtcrime.securesms.recipients.Recipient) UnidentifiedAccessPair(org.whispersystems.signalservice.api.crypto.UnidentifiedAccessPair) DistributionId(org.whispersystems.signalservice.api.push.DistributionId) InvalidKeyException(org.whispersystems.libsignal.InvalidKeyException) LinkedList(java.util.LinkedList) SendMessageResult(org.whispersystems.signalservice.api.messages.SendMessageResult) ContentHint(org.whispersystems.signalservice.api.crypto.ContentHint) UnidentifiedAccess(org.whispersystems.signalservice.api.crypto.UnidentifiedAccess) AtomicLong(java.util.concurrent.atomic.AtomicLong) InvalidUnidentifiedAccessHeaderException(org.whispersystems.signalservice.internal.push.exceptions.InvalidUnidentifiedAccessHeaderException) WorkerThread(androidx.annotation.WorkerThread)

Example 85 with MessageId

use of org.thoughtcrime.securesms.database.model.MessageId in project Signal-Android by signalapp.

the class MessageContentProcessor method handleEndSessionMessage.

@Nullable
private MessageId handleEndSessionMessage(@NonNull SignalServiceContent content, @NonNull Optional<Long> smsMessageId, @NonNull Recipient senderRecipient) {
    log(content.getTimestamp(), "End session message.");
    MessageDatabase smsDatabase = SignalDatabase.sms();
    IncomingTextMessage incomingTextMessage = new IncomingTextMessage(senderRecipient.getId(), content.getSenderDevice(), content.getTimestamp(), content.getServerReceivedTimestamp(), System.currentTimeMillis(), "", Optional.absent(), 0, content.isNeedsReceipt(), content.getServerUuid());
    Optional<InsertResult> insertResult;
    if (!smsMessageId.isPresent()) {
        IncomingEndSessionMessage incomingEndSessionMessage = new IncomingEndSessionMessage(incomingTextMessage);
        insertResult = smsDatabase.insertMessageInbox(incomingEndSessionMessage);
    } else {
        smsDatabase.markAsEndSession(smsMessageId.get());
        insertResult = Optional.of(new InsertResult(smsMessageId.get(), smsDatabase.getThreadIdForMessage(smsMessageId.get())));
    }
    if (insertResult.isPresent()) {
        ApplicationDependencies.getProtocolStore().aci().deleteAllSessions(content.getSender().getIdentifier());
        SecurityEvent.broadcastSecurityUpdateEvent(context);
        ApplicationDependencies.getMessageNotifier().updateNotification(context, insertResult.get().getThreadId());
        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) IncomingEndSessionMessage(org.thoughtcrime.securesms.sms.IncomingEndSessionMessage) IncomingTextMessage(org.thoughtcrime.securesms.sms.IncomingTextMessage) MessageId(org.thoughtcrime.securesms.database.model.MessageId) SyncMessageId(org.thoughtcrime.securesms.database.MessageDatabase.SyncMessageId) Nullable(androidx.annotation.Nullable)

Aggregations

MessageId (org.thoughtcrime.securesms.database.model.MessageId)90 RecipientId (org.thoughtcrime.securesms.recipients.RecipientId)40 NonNull (androidx.annotation.NonNull)30 Recipient (org.thoughtcrime.securesms.recipients.Recipient)30 Nullable (androidx.annotation.Nullable)28 LinkedList (java.util.LinkedList)24 List (java.util.List)24 SyncMessageId (org.thoughtcrime.securesms.database.MessageDatabase.SyncMessageId)24 Context (android.content.Context)22 IOException (java.io.IOException)22 Log (org.signal.core.util.logging.Log)22 ApplicationDependencies (org.thoughtcrime.securesms.dependencies.ApplicationDependencies)22 SignalServiceDataMessage (org.whispersystems.signalservice.api.messages.SignalServiceDataMessage)22 ContentValues (android.content.ContentValues)20 Collections (java.util.Collections)20 Attachment (org.thoughtcrime.securesms.attachments.Attachment)20 MessageDatabase (org.thoughtcrime.securesms.database.MessageDatabase)20 Cursor (android.database.Cursor)18 ArrayList (java.util.ArrayList)18 TextSecurePreferences (org.thoughtcrime.securesms.util.TextSecurePreferences)18