diff --git a/src/org/thoughtcrime/securesms/database/EncryptingSmsDatabase.java b/src/org/thoughtcrime/securesms/database/EncryptingSmsDatabase.java index 283edc66a4..fc4bb7ba93 100644 --- a/src/org/thoughtcrime/securesms/database/EncryptingSmsDatabase.java +++ b/src/org/thoughtcrime/securesms/database/EncryptingSmsDatabase.java @@ -35,6 +35,7 @@ import org.thoughtcrime.securesms.sms.IncomingTextMessage; import org.thoughtcrime.securesms.sms.OutgoingTextMessage; import org.thoughtcrime.securesms.util.LRUCache; import org.whispersystems.libsignal.InvalidMessageException; +import org.whispersystems.libsignal.util.guava.Optional; import java.lang.ref.SoftReference; import java.util.Collections; @@ -78,8 +79,8 @@ public class EncryptingSmsDatabase extends SmsDatabase { return insertMessageOutbox(threadId, message, type, forceSms, timestamp); } - public Pair insertMessageInbox(@NonNull MasterSecretUnion masterSecret, - @NonNull IncomingTextMessage message) + public Optional insertMessageInbox(@NonNull MasterSecretUnion masterSecret, + @NonNull IncomingTextMessage message) { if (masterSecret.getMasterSecret().isPresent()) { return insertMessageInbox(masterSecret.getMasterSecret().get(), message); @@ -88,8 +89,8 @@ public class EncryptingSmsDatabase extends SmsDatabase { } } - private Pair insertMessageInbox(@NonNull MasterSecret masterSecret, - @NonNull IncomingTextMessage message) + private Optional insertMessageInbox(@NonNull MasterSecret masterSecret, + @NonNull IncomingTextMessage message) { long type = Types.BASE_INBOX_TYPE | Types.ENCRYPTION_SYMMETRIC_BIT; @@ -98,8 +99,8 @@ public class EncryptingSmsDatabase extends SmsDatabase { return insertMessageInbox(message, type); } - private Pair insertMessageInbox(@NonNull AsymmetricMasterSecret masterSecret, - @NonNull IncomingTextMessage message) + private Optional insertMessageInbox(@NonNull AsymmetricMasterSecret masterSecret, + @NonNull IncomingTextMessage message) { long type = Types.BASE_INBOX_TYPE | Types.ENCRYPTION_ASYMMETRIC_BIT; diff --git a/src/org/thoughtcrime/securesms/database/MessagingDatabase.java b/src/org/thoughtcrime/securesms/database/MessagingDatabase.java index 114eff3c69..6a660aa604 100644 --- a/src/org/thoughtcrime/securesms/database/MessagingDatabase.java +++ b/src/org/thoughtcrime/securesms/database/MessagingDatabase.java @@ -235,4 +235,21 @@ public abstract class MessagingDatabase extends Database implements MmsSmsColumn } } + public static class InsertResult { + private final long messageId; + private final long threadId; + + public InsertResult(long messageId, long threadId) { + this.messageId = messageId; + this.threadId = threadId; + } + + public long getMessageId() { + return messageId; + } + + public long getThreadId() { + return threadId; + } + } } diff --git a/src/org/thoughtcrime/securesms/database/MmsDatabase.java b/src/org/thoughtcrime/securesms/database/MmsDatabase.java index 72ed622f99..9c186c7104 100644 --- a/src/org/thoughtcrime/securesms/database/MmsDatabase.java +++ b/src/org/thoughtcrime/securesms/database/MmsDatabase.java @@ -693,10 +693,10 @@ public class MmsDatabase extends MessagingDatabase { } } - private Pair insertMessageInbox(MasterSecretUnion masterSecret, - IncomingMediaMessage retrieved, - String contentLocation, - long threadId, long mailbox) + private Optional insertMessageInbox(MasterSecretUnion masterSecret, + IncomingMediaMessage retrieved, + String contentLocation, + long threadId, long mailbox) throws MmsException { if (threadId == -1 || retrieved.isGroupMessage()) { @@ -729,6 +729,11 @@ public class MmsDatabase extends MessagingDatabase { contentValues.put(DATE_SENT, contentValues.getAsLong(DATE_RECEIVED)); } + if (retrieved.isPushMessage() && isDuplicate(retrieved, threadId)) { + Log.w(TAG, "Ignoring duplicate media message (" + retrieved.getSentTimeMillis() + ")"); + return Optional.absent(); + } + long messageId = insertMediaMessage(masterSecret, retrieved.getAddresses(), retrieved.getBody(), retrieved.getAttachments(), contentValues); @@ -741,12 +746,12 @@ public class MmsDatabase extends MessagingDatabase { notifyConversationListeners(threadId); jobManager.add(new TrimThreadJob(context, threadId)); - return new Pair<>(messageId, threadId); + return Optional.of(new InsertResult(messageId, threadId)); } - public Pair insertMessageInbox(MasterSecretUnion masterSecret, - IncomingMediaMessage retrieved, - String contentLocation, long threadId) + public Optional insertMessageInbox(MasterSecretUnion masterSecret, + IncomingMediaMessage retrieved, + String contentLocation, long threadId) throws MmsException { long type = Types.BASE_INBOX_TYPE; @@ -768,9 +773,9 @@ public class MmsDatabase extends MessagingDatabase { return insertMessageInbox(masterSecret, retrieved, contentLocation, threadId, type); } - public Pair insertSecureDecryptedMessageInbox(MasterSecretUnion masterSecret, - IncomingMediaMessage retrieved, - long threadId) + public Optional insertSecureDecryptedMessageInbox(MasterSecretUnion masterSecret, + IncomingMediaMessage retrieved, + long threadId) throws MmsException { long type = Types.BASE_INBOX_TYPE | Types.SECURE_MESSAGE_BIT; @@ -990,6 +995,20 @@ public class MmsDatabase extends MessagingDatabase { deleteThreads(singleThreadSet); } + private boolean isDuplicate(IncomingMediaMessage message, long threadId) { + SQLiteDatabase database = databaseHelper.getReadableDatabase(); + Cursor cursor = database.query(TABLE_NAME, null, DATE_SENT + " = ? AND " + ADDRESS + " = ? AND " + THREAD_ID + " = ?", + new String[]{String.valueOf(message.getSentTimeMillis()), message.getAddresses().getFrom(), String.valueOf(threadId)}, + null, null, null, "1"); + + try { + return cursor != null && cursor.moveToFirst(); + } finally { + if (cursor != null) cursor.close(); + } + } + + /*package*/ void deleteThreads(Set threadIds) { SQLiteDatabase db = databaseHelper.getWritableDatabase(); String where = ""; diff --git a/src/org/thoughtcrime/securesms/database/SmsDatabase.java b/src/org/thoughtcrime/securesms/database/SmsDatabase.java index 33b46e8250..f91ac3b023 100644 --- a/src/org/thoughtcrime/securesms/database/SmsDatabase.java +++ b/src/org/thoughtcrime/securesms/database/SmsDatabase.java @@ -42,6 +42,7 @@ import org.thoughtcrime.securesms.sms.IncomingTextMessage; import org.thoughtcrime.securesms.sms.OutgoingTextMessage; import org.thoughtcrime.securesms.util.JsonUtils; import org.whispersystems.jobqueue.JobManager; +import org.whispersystems.libsignal.util.guava.Optional; import org.whispersystems.signalservice.api.util.InvalidNumberException; import java.io.IOException; @@ -482,7 +483,7 @@ public class SmsDatabase extends MessagingDatabase { return new Pair<>(messageId, threadId); } - protected Pair insertMessageInbox(IncomingTextMessage message, long type) { + protected Optional insertMessageInbox(IncomingTextMessage message, long type) { if (message.isJoined()) { type = (type & (Types.TOTAL_MASK - Types.BASE_TYPE_MASK)) | Types.JOINED_TYPE; } else if (message.isPreKeyBundle()) { @@ -546,24 +547,29 @@ public class SmsDatabase extends MessagingDatabase { values.put(TYPE, type); values.put(THREAD_ID, threadId); - SQLiteDatabase db = databaseHelper.getWritableDatabase(); - long messageId = db.insert(TABLE_NAME, null, values); + if (message.isPush() && isDuplicate(message, threadId)) { + Log.w(TAG, "Duplicate message (" + message.getSentTimestampMillis() + "), ignoring..."); + return Optional.absent(); + } else { + SQLiteDatabase db = databaseHelper.getWritableDatabase(); + long messageId = db.insert(TABLE_NAME, null, values); - if (unread) { - DatabaseFactory.getThreadDatabase(context).setUnread(threadId); - } + if (unread) { + DatabaseFactory.getThreadDatabase(context).setUnread(threadId); + } - if (!message.isIdentityUpdate()) { - DatabaseFactory.getThreadDatabase(context).update(threadId, true); - } + if (!message.isIdentityUpdate()) { + DatabaseFactory.getThreadDatabase(context).update(threadId, true); + } - notifyConversationListeners(threadId); - jobManager.add(new TrimThreadJob(context, threadId)); + notifyConversationListeners(threadId); + jobManager.add(new TrimThreadJob(context, threadId)); - return new Pair<>(messageId, threadId); + return Optional.of(new InsertResult(messageId, threadId)); + } } - public Pair insertMessageInbox(IncomingTextMessage message) { + public Optional insertMessageInbox(IncomingTextMessage message) { return insertMessageInbox(message, Types.BASE_INBOX_TYPE); } @@ -653,6 +659,19 @@ public class SmsDatabase extends MessagingDatabase { return threadDeleted; } + private boolean isDuplicate(IncomingTextMessage message, long threadId) { + SQLiteDatabase database = databaseHelper.getReadableDatabase(); + Cursor cursor = database.query(TABLE_NAME, null, DATE_SENT + " = ? AND " + ADDRESS + " = ? AND " + THREAD_ID + " = ?", + new String[]{String.valueOf(message.getSentTimestampMillis()), message.getSender(), String.valueOf(threadId)}, + null, null, null, "1"); + + try { + return cursor != null && cursor.moveToFirst(); + } finally { + if (cursor != null) cursor.close(); + } + } + /*package */void deleteThread(long threadId) { SQLiteDatabase db = databaseHelper.getWritableDatabase(); db.delete(TABLE_NAME, THREAD_ID + " = ?", new String[] {threadId+""}); @@ -817,4 +836,5 @@ public class SmsDatabase extends MessagingDatabase { cursor.close(); } } + } diff --git a/src/org/thoughtcrime/securesms/groups/GroupMessageProcessor.java b/src/org/thoughtcrime/securesms/groups/GroupMessageProcessor.java index 91cf18e0d2..fdd050875a 100644 --- a/src/org/thoughtcrime/securesms/groups/GroupMessageProcessor.java +++ b/src/org/thoughtcrime/securesms/groups/GroupMessageProcessor.java @@ -5,7 +5,6 @@ import android.content.Context; import android.support.annotation.NonNull; import android.support.annotation.Nullable; import android.util.Log; -import android.util.Pair; import com.google.protobuf.ByteString; @@ -15,6 +14,7 @@ import org.thoughtcrime.securesms.database.DatabaseFactory; import org.thoughtcrime.securesms.database.EncryptingSmsDatabase; import org.thoughtcrime.securesms.database.GroupDatabase; import org.thoughtcrime.securesms.database.MmsDatabase; +import org.thoughtcrime.securesms.database.MessagingDatabase.InsertResult; import org.thoughtcrime.securesms.jobs.AvatarDownloadJob; import org.thoughtcrime.securesms.jobs.PushGroupUpdateJob; import org.thoughtcrime.securesms.mms.OutgoingGroupMediaMessage; @@ -216,10 +216,14 @@ public class GroupMessageProcessor { IncomingTextMessage incoming = new IncomingTextMessage(envelope.getSource(), envelope.getSourceDevice(), envelope.getTimestamp(), body, Optional.of(group), 0); IncomingGroupMessage groupMessage = new IncomingGroupMessage(incoming, storage, body); - Pair messageAndThreadId = smsDatabase.insertMessageInbox(masterSecret, groupMessage); - MessageNotifier.updateNotification(context, masterSecret.getMasterSecret().orNull(), messageAndThreadId.second); + Optional insertResult = smsDatabase.insertMessageInbox(masterSecret, groupMessage); - return messageAndThreadId.second; + if (insertResult.isPresent()) { + MessageNotifier.updateNotification(context, masterSecret.getMasterSecret().orNull(), insertResult.get().getThreadId()); + return insertResult.get().getThreadId(); + } else { + return null; + } } } catch (MmsException e) { Log.w(TAG, e); diff --git a/src/org/thoughtcrime/securesms/jobs/MmsDownloadJob.java b/src/org/thoughtcrime/securesms/jobs/MmsDownloadJob.java index 2d21b01fc4..277f054f27 100644 --- a/src/org/thoughtcrime/securesms/jobs/MmsDownloadJob.java +++ b/src/org/thoughtcrime/securesms/jobs/MmsDownloadJob.java @@ -11,6 +11,7 @@ import org.thoughtcrime.securesms.crypto.MasterSecret; import org.thoughtcrime.securesms.crypto.MasterSecretUnion; import org.thoughtcrime.securesms.database.AttachmentDatabase; import org.thoughtcrime.securesms.database.DatabaseFactory; +import org.thoughtcrime.securesms.database.MessagingDatabase.InsertResult; import org.thoughtcrime.securesms.database.MmsDatabase; import org.thoughtcrime.securesms.jobs.requirements.MasterSecretRequirement; import org.thoughtcrime.securesms.mms.ApnUnavailableException; @@ -194,12 +195,14 @@ public class MmsDownloadJob extends MasterSecretJob { - IncomingMediaMessage message = new IncomingMediaMessage(from, to, cc, body, retrieved.getDate() * 1000L, attachments, subscriptionId, 0, false); + IncomingMediaMessage message = new IncomingMediaMessage(from, to, cc, body, retrieved.getDate() * 1000L, attachments, subscriptionId, 0, false); + Optional insertResult = database.insertMessageInbox(new MasterSecretUnion(masterSecret), + message, contentLocation, threadId); - Pair messageAndThreadId = database.insertMessageInbox(new MasterSecretUnion(masterSecret), - message, contentLocation, threadId); - database.delete(messageId); - MessageNotifier.updateNotification(context, masterSecret, messageAndThreadId.second); + if (insertResult.isPresent()) { + database.delete(messageId); + MessageNotifier.updateNotification(context, masterSecret, insertResult.get().getThreadId()); + } } private void handleDownloadError(MasterSecret masterSecret, long messageId, long threadId, diff --git a/src/org/thoughtcrime/securesms/jobs/PushDecryptJob.java b/src/org/thoughtcrime/securesms/jobs/PushDecryptJob.java index 99bbff1d1c..e58e7b2339 100644 --- a/src/org/thoughtcrime/securesms/jobs/PushDecryptJob.java +++ b/src/org/thoughtcrime/securesms/jobs/PushDecryptJob.java @@ -18,6 +18,7 @@ import org.thoughtcrime.securesms.crypto.storage.TextSecureSessionStore; import org.thoughtcrime.securesms.database.DatabaseFactory; import org.thoughtcrime.securesms.database.EncryptingSmsDatabase; import org.thoughtcrime.securesms.database.GroupDatabase; +import org.thoughtcrime.securesms.database.MessagingDatabase.InsertResult; import org.thoughtcrime.securesms.database.MessagingDatabase.SyncMessageId; import org.thoughtcrime.securesms.database.MmsDatabase; import org.thoughtcrime.securesms.database.NoSuchMessageException; @@ -196,23 +197,26 @@ public class PushDecryptJob extends ContextJob { message.getTimestamp(), "", Optional.absent(), 0); - long threadId; + Long threadId; if (!smsMessageId.isPresent()) { IncomingEndSessionMessage incomingEndSessionMessage = new IncomingEndSessionMessage(incomingTextMessage); - Pair messageAndThreadId = smsDatabase.insertMessageInbox(masterSecret, incomingEndSessionMessage); + Optional insertResult = smsDatabase.insertMessageInbox(masterSecret, incomingEndSessionMessage); - threadId = messageAndThreadId.second; + if (insertResult.isPresent()) threadId = insertResult.get().getThreadId(); + else threadId = null; } else { smsDatabase.markAsEndSession(smsMessageId.get()); threadId = smsDatabase.getThreadIdForMessage(smsMessageId.get()); } - SessionStore sessionStore = new TextSecureSessionStore(context); - sessionStore.deleteAllSessions(envelope.getSource()); + if (threadId != null) { + SessionStore sessionStore = new TextSecureSessionStore(context); + sessionStore.deleteAllSessions(envelope.getSource()); - SecurityEvent.broadcastSecurityUpdateEvent(context); - MessageNotifier.updateNotification(context, masterSecret.getMasterSecret().orNull(), threadId); + SecurityEvent.broadcastSecurityUpdateEvent(context); + MessageNotifier.updateNotification(context, masterSecret.getMasterSecret().orNull(), threadId); + } } private void handleGroupMessage(@NonNull MasterSecretUnion masterSecret, @@ -363,21 +367,24 @@ public class PushDecryptJob extends ContextJob { handleExpirationUpdate(masterSecret, envelope, message, Optional.absent()); } - Pair messageAndThreadId = database.insertSecureDecryptedMessageInbox(masterSecret, mediaMessage, -1); - List attachments = DatabaseFactory.getAttachmentDatabase(context).getAttachmentsForMessage(messageAndThreadId.first); + Optional insertResult = database.insertSecureDecryptedMessageInbox(masterSecret, mediaMessage, -1); - for (DatabaseAttachment attachment : attachments) { - ApplicationContext.getInstance(context) - .getJobManager() - .add(new AttachmentDownloadJob(context, messageAndThreadId.first, - attachment.getAttachmentId())); - } + if (insertResult.isPresent()) { + List attachments = DatabaseFactory.getAttachmentDatabase(context).getAttachmentsForMessage(insertResult.get().getMessageId()); - if (smsMessageId.isPresent()) { - DatabaseFactory.getSmsDatabase(context).deleteMessage(smsMessageId.get()); - } + for (DatabaseAttachment attachment : attachments) { + ApplicationContext.getInstance(context) + .getJobManager() + .add(new AttachmentDownloadJob(context, insertResult.get().getMessageId(), + attachment.getAttachmentId())); + } - MessageNotifier.updateNotification(context, masterSecret.getMasterSecret().orNull(), messageAndThreadId.second); + if (smsMessageId.isPresent()) { + DatabaseFactory.getSmsDatabase(context).deleteMessage(smsMessageId.get()); + } + + MessageNotifier.updateNotification(context, masterSecret.getMasterSecret().orNull(), insertResult.get().getThreadId()); + } } private long handleSynchronizeSentExpirationUpdate(@NonNull MasterSecretUnion masterSecret, @@ -466,10 +473,10 @@ public class PushDecryptJob extends ContextJob { handleExpirationUpdate(masterSecret, envelope, message, Optional.absent()); } - Pair messageAndThreadId; + Long threadId; if (smsMessageId.isPresent() && !message.getGroupInfo().isPresent()) { - messageAndThreadId = database.updateBundleMessageBody(masterSecret, smsMessageId.get(), body); + threadId = database.updateBundleMessageBody(masterSecret, smsMessageId.get(), body).second; } else { IncomingTextMessage textMessage = new IncomingTextMessage(envelope.getSource(), envelope.getSourceDevice(), @@ -478,12 +485,17 @@ public class PushDecryptJob extends ContextJob { message.getExpiresInSeconds() * 1000); textMessage = new IncomingEncryptedMessage(textMessage, body); - messageAndThreadId = database.insertMessageInbox(masterSecret, textMessage); + Optional insertResult = database.insertMessageInbox(masterSecret, textMessage); + + if (insertResult.isPresent()) threadId = insertResult.get().getThreadId(); + else threadId = null; if (smsMessageId.isPresent()) database.deleteMessage(smsMessageId.get()); } - MessageNotifier.updateNotification(context, masterSecret.getMasterSecret().orNull(), messageAndThreadId.second); + if (threadId != null) { + MessageNotifier.updateNotification(context, masterSecret.getMasterSecret().orNull(), threadId); + } } private long handleSynchronizeSentTextMessage(@NonNull MasterSecretUnion masterSecret, @@ -527,9 +539,12 @@ public class PushDecryptJob extends ContextJob { EncryptingSmsDatabase smsDatabase = DatabaseFactory.getEncryptingSmsDatabase(context); if (!smsMessageId.isPresent()) { - Pair messageAndThreadId = insertPlaceholder(envelope); - smsDatabase.markAsInvalidVersionKeyExchange(messageAndThreadId.first); - MessageNotifier.updateNotification(context, masterSecret.getMasterSecret().orNull(), messageAndThreadId.second); + Optional insertResult = insertPlaceholder(envelope); + + if (insertResult.isPresent()) { + smsDatabase.markAsInvalidVersionKeyExchange(insertResult.get().getMessageId()); + MessageNotifier.updateNotification(context, masterSecret.getMasterSecret().orNull(), insertResult.get().getThreadId()); + } } else { smsDatabase.markAsInvalidVersionKeyExchange(smsMessageId.get()); } @@ -542,9 +557,12 @@ public class PushDecryptJob extends ContextJob { EncryptingSmsDatabase smsDatabase = DatabaseFactory.getEncryptingSmsDatabase(context); if (!smsMessageId.isPresent()) { - Pair messageAndThreadId = insertPlaceholder(envelope); - smsDatabase.markAsDecryptFailed(messageAndThreadId.first); - MessageNotifier.updateNotification(context, masterSecret.getMasterSecret().orNull(), messageAndThreadId.second); + Optional insertResult = insertPlaceholder(envelope); + + if (insertResult.isPresent()) { + smsDatabase.markAsDecryptFailed(insertResult.get().getMessageId()); + MessageNotifier.updateNotification(context, masterSecret.getMasterSecret().orNull(), insertResult.get().getThreadId()); + } } else { smsDatabase.markAsDecryptFailed(smsMessageId.get()); } @@ -557,9 +575,12 @@ public class PushDecryptJob extends ContextJob { EncryptingSmsDatabase smsDatabase = DatabaseFactory.getEncryptingSmsDatabase(context); if (!smsMessageId.isPresent()) { - Pair messageAndThreadId = insertPlaceholder(envelope); - smsDatabase.markAsNoSession(messageAndThreadId.first); - MessageNotifier.updateNotification(context, masterSecret.getMasterSecret().orNull(), messageAndThreadId.second); + Optional insertResult = insertPlaceholder(envelope); + + if (insertResult.isPresent()) { + smsDatabase.markAsNoSession(insertResult.get().getMessageId()); + MessageNotifier.updateNotification(context, masterSecret.getMasterSecret().orNull(), insertResult.get().getThreadId()); + } } else { smsDatabase.markAsNoSession(smsMessageId.get()); } @@ -572,9 +593,12 @@ public class PushDecryptJob extends ContextJob { EncryptingSmsDatabase smsDatabase = DatabaseFactory.getEncryptingSmsDatabase(context); if (!smsMessageId.isPresent()) { - Pair messageAndThreadId = insertPlaceholder(envelope); - smsDatabase.markAsLegacyVersion(messageAndThreadId.first); - MessageNotifier.updateNotification(context, masterSecret.getMasterSecret().orNull(), messageAndThreadId.second); + Optional insertResult = insertPlaceholder(envelope); + + if (insertResult.isPresent()) { + smsDatabase.markAsLegacyVersion(insertResult.get().getMessageId()); + MessageNotifier.updateNotification(context, masterSecret.getMasterSecret().orNull(), insertResult.get().getThreadId()); + } } else { smsDatabase.markAsLegacyVersion(smsMessageId.get()); } @@ -613,11 +637,13 @@ public class PushDecryptJob extends ContextJob { Optional.absent(), 0); if (!smsMessageId.isPresent()) { - IncomingPreKeyBundleMessage bundleMessage = new IncomingPreKeyBundleMessage(textMessage, encoded); - Pair messageAndThreadId = database.insertMessageInbox(masterSecret, bundleMessage); + IncomingPreKeyBundleMessage bundleMessage = new IncomingPreKeyBundleMessage(textMessage, encoded); + Optional insertResult = database.insertMessageInbox(masterSecret, bundleMessage); - database.setMismatchedIdentity(messageAndThreadId.first, recipientId, identityKey); - MessageNotifier.updateNotification(context, masterSecret.getMasterSecret().orNull(), messageAndThreadId.second); + if (insertResult.isPresent()) { + database.setMismatchedIdentity(insertResult.get().getMessageId(), recipientId, identityKey); + MessageNotifier.updateNotification(context, masterSecret.getMasterSecret().orNull(), insertResult.get().getThreadId()); + } } else { database.updateMessageBody(masterSecret, smsMessageId.get(), encoded); database.markAsPreKeyBundle(smsMessageId.get()); @@ -628,7 +654,7 @@ public class PushDecryptJob extends ContextJob { } } - private Pair insertPlaceholder(@NonNull SignalServiceEnvelope envelope) { + private Optional insertPlaceholder(@NonNull SignalServiceEnvelope envelope) { EncryptingSmsDatabase database = DatabaseFactory.getEncryptingSmsDatabase(context); IncomingTextMessage textMessage = new IncomingTextMessage(envelope.getSource(), envelope.getSourceDevice(), envelope.getTimestamp(), "", diff --git a/src/org/thoughtcrime/securesms/jobs/SmsReceiveJob.java b/src/org/thoughtcrime/securesms/jobs/SmsReceiveJob.java index 0bfa174b42..44fa723b2e 100644 --- a/src/org/thoughtcrime/securesms/jobs/SmsReceiveJob.java +++ b/src/org/thoughtcrime/securesms/jobs/SmsReceiveJob.java @@ -3,13 +3,13 @@ package org.thoughtcrime.securesms.jobs; import android.content.Context; import android.telephony.SmsMessage; import android.util.Log; -import android.util.Pair; import org.thoughtcrime.securesms.crypto.MasterSecret; import org.thoughtcrime.securesms.crypto.MasterSecretUnion; import org.thoughtcrime.securesms.crypto.MasterSecretUtil; import org.thoughtcrime.securesms.database.DatabaseFactory; import org.thoughtcrime.securesms.database.EncryptingSmsDatabase; +import org.thoughtcrime.securesms.database.MessagingDatabase.InsertResult; import org.thoughtcrime.securesms.notifications.MessageNotifier; import org.thoughtcrime.securesms.recipients.RecipientFactory; import org.thoughtcrime.securesms.recipients.Recipients; @@ -57,8 +57,11 @@ public class SmsReceiveJob extends ContextJob { } if (message.isPresent() && !isBlocked(message.get())) { - Pair messageAndThreadId = storeMessage(masterSecretUnion, message.get()); - MessageNotifier.updateNotification(context, masterSecret, messageAndThreadId.second); + Optional insertResult = storeMessage(masterSecretUnion, message.get()); + + if (insertResult.isPresent()) { + MessageNotifier.updateNotification(context, masterSecret, insertResult.get().getThreadId()); + } } else if (message.isPresent()) { Log.w(TAG, "*** Received blocked SMS, ignoring..."); } @@ -83,20 +86,18 @@ public class SmsReceiveJob extends ContextJob { return false; } - private Pair storeMessage(MasterSecretUnion masterSecret, IncomingTextMessage message) { + private Optional storeMessage(MasterSecretUnion masterSecret, IncomingTextMessage message) { EncryptingSmsDatabase database = DatabaseFactory.getEncryptingSmsDatabase(context); - Pair messageAndThreadId; - if (message.isSecureMessage()) { - IncomingTextMessage placeholder = new IncomingTextMessage(message, ""); - messageAndThreadId = database.insertMessageInbox(placeholder); - database.markAsLegacyVersion(messageAndThreadId.first); + IncomingTextMessage placeholder = new IncomingTextMessage(message, ""); + Optional insertResult = database.insertMessageInbox(placeholder); + database.markAsLegacyVersion(insertResult.get().getMessageId()); + + return insertResult; } else { - messageAndThreadId = database.insertMessageInbox(masterSecret, message); + return database.insertMessageInbox(masterSecret, message); } - - return messageAndThreadId; } private Optional assembleMessageFragments(Object[] pdus, int subscriptionId) { diff --git a/src/org/thoughtcrime/securesms/util/DirectoryHelper.java b/src/org/thoughtcrime/securesms/util/DirectoryHelper.java index 70d0c0d723..6412dc86f6 100644 --- a/src/org/thoughtcrime/securesms/util/DirectoryHelper.java +++ b/src/org/thoughtcrime/securesms/util/DirectoryHelper.java @@ -10,7 +10,6 @@ import android.provider.ContactsContract; import android.support.annotation.NonNull; import android.support.annotation.Nullable; import android.util.Log; -import android.util.Pair; import org.thoughtcrime.securesms.ApplicationContext; import org.thoughtcrime.securesms.R; @@ -18,6 +17,7 @@ import org.thoughtcrime.securesms.crypto.MasterSecret; import org.thoughtcrime.securesms.crypto.SessionUtil; import org.thoughtcrime.securesms.database.DatabaseFactory; import org.thoughtcrime.securesms.database.NotInDirectoryException; +import org.thoughtcrime.securesms.database.MessagingDatabase.InsertResult; import org.thoughtcrime.securesms.database.TextSecureDirectory; import org.thoughtcrime.securesms.jobs.MultiDeviceContactUpdateJob; import org.thoughtcrime.securesms.notifications.MessageNotifier; @@ -223,14 +223,16 @@ public class DirectoryHelper { for (String newUser : newUsers) { if (!SessionUtil.hasSession(context, masterSecret, newUser) && !Util.isOwnNumber(context, newUser)) { - IncomingJoinedMessage message = new IncomingJoinedMessage(newUser); - Pair smsAndThreadId = DatabaseFactory.getSmsDatabase(context).insertMessageInbox(message); - - int hour = Calendar.getInstance().get(Calendar.HOUR_OF_DAY); - if (hour >= 9 && hour < 23) { - MessageNotifier.updateNotification(context, masterSecret, false, smsAndThreadId.second, true); - } else { - MessageNotifier.updateNotification(context, masterSecret, false, smsAndThreadId.second, false); + IncomingJoinedMessage message = new IncomingJoinedMessage(newUser); + Optional insertResult = DatabaseFactory.getSmsDatabase(context).insertMessageInbox(message); + + if (insertResult.isPresent()) { + int hour = Calendar.getInstance().get(Calendar.HOUR_OF_DAY); + if (hour >= 9 && hour < 23) { + MessageNotifier.updateNotification(context, masterSecret, false, insertResult.get().getThreadId(), true); + } else { + MessageNotifier.updateNotification(context, masterSecret, false, insertResult.get().getThreadId(), false); + } } } }