From 922f6d89e975a9b994c37bc6eaf611eb1cf4b92c Mon Sep 17 00:00:00 2001 From: Greyson Parrelli Date: Tue, 28 May 2019 15:21:19 -0400 Subject: [PATCH] Render placeholders for unsupported messages. --- res/values/strings.xml | 4 +++ .../securesms/database/MmsSmsColumns.java | 5 ++++ .../securesms/database/SmsDatabase.java | 4 +++ .../database/model/SmsMessageRecord.java | 2 ++ .../database/model/ThreadRecord.java | 2 ++ .../securesms/jobs/PushDecryptJob.java | 30 ++++++++++++++++++- 6 files changed, 46 insertions(+), 1 deletion(-) diff --git a/res/values/strings.xml b/res/values/strings.xml index 19dbde81f8..9ae054a6c2 100644 --- a/res/values/strings.xml +++ b/res/values/strings.xml @@ -663,6 +663,9 @@ You reset the secure session. %s reset the secure session. Duplicate message. + + This message could not be processed because it was sent from a newer version of Signal. You can ask your contact to send this message again after you update. + Stickers @@ -700,6 +703,7 @@ Your safety number with %s has changed. You marked verified You marked unverified + Message could not be processed Signal update diff --git a/src/org/thoughtcrime/securesms/database/MmsSmsColumns.java b/src/org/thoughtcrime/securesms/database/MmsSmsColumns.java index 3872472a6d..118989623e 100644 --- a/src/org/thoughtcrime/securesms/database/MmsSmsColumns.java +++ b/src/org/thoughtcrime/securesms/database/MmsSmsColumns.java @@ -31,6 +31,7 @@ public interface MmsSmsColumns { protected static final long OUTGOING_CALL_TYPE = 2; protected static final long MISSED_CALL_TYPE = 3; protected static final long JOINED_TYPE = 4; + protected static final long UNSUPPORTED_MESSAGE_TYPE = 5; protected static final long BASE_INBOX_TYPE = 20; protected static final long BASE_OUTBOX_TYPE = 21; @@ -142,6 +143,10 @@ public interface MmsSmsColumns { return (type & BASE_TYPE_MASK) == JOINED_TYPE; } + public static boolean isUnsupportedMessageType(long type) { + return (type & BASE_TYPE_MASK) == UNSUPPORTED_MESSAGE_TYPE; + } + public static boolean isSecureType(long type) { return (type & SECURE_MESSAGE_BIT) != 0; } diff --git a/src/org/thoughtcrime/securesms/database/SmsDatabase.java b/src/org/thoughtcrime/securesms/database/SmsDatabase.java index 9db2be22bc..3329e08ea3 100644 --- a/src/org/thoughtcrime/securesms/database/SmsDatabase.java +++ b/src/org/thoughtcrime/securesms/database/SmsDatabase.java @@ -217,6 +217,10 @@ public class SmsDatabase extends MessagingDatabase { updateTypeBitmask(id, Types.ENCRYPTION_MASK, Types.ENCRYPTION_REMOTE_NO_SESSION_BIT); } + public void markAsUnsupportedProtocolVersion(long id) { + updateTypeBitmask(id, Types.BASE_TYPE_MASK, Types.UNSUPPORTED_MESSAGE_TYPE); + } + public void markAsLegacyVersion(long id) { updateTypeBitmask(id, Types.ENCRYPTION_MASK, Types.ENCRYPTION_REMOTE_LEGACY_BIT); } diff --git a/src/org/thoughtcrime/securesms/database/model/SmsMessageRecord.java b/src/org/thoughtcrime/securesms/database/model/SmsMessageRecord.java index beede83f28..ea2e1d3af1 100644 --- a/src/org/thoughtcrime/securesms/database/model/SmsMessageRecord.java +++ b/src/org/thoughtcrime/securesms/database/model/SmsMessageRecord.java @@ -84,6 +84,8 @@ public class SmsMessageRecord extends MessageRecord { return emphasisAdded(context.getString(R.string.SmsMessageRecord_secure_session_reset)); } else if (isEndSession()) { return emphasisAdded(context.getString(R.string.SmsMessageRecord_secure_session_reset_s, getIndividualRecipient().toShortString())); + } else if (SmsDatabase.Types.isUnsupportedMessageType(type)) { + return emphasisAdded(context.getString(R.string.SmsMessageRecord_this_message_could_not_be_processed_because_it_was_sent_from_a_newer_version)); } else { return super.getDisplayBody(context); } diff --git a/src/org/thoughtcrime/securesms/database/model/ThreadRecord.java b/src/org/thoughtcrime/securesms/database/model/ThreadRecord.java index 12a38cc253..57d84a895b 100644 --- a/src/org/thoughtcrime/securesms/database/model/ThreadRecord.java +++ b/src/org/thoughtcrime/securesms/database/model/ThreadRecord.java @@ -109,6 +109,8 @@ public class ThreadRecord extends DisplayRecord { return emphasisAdded(context.getString(R.string.ThreadRecord_you_marked_verified)); } else if (SmsDatabase.Types.isIdentityDefault(type)) { return emphasisAdded(context.getString(R.string.ThreadRecord_you_marked_unverified)); + } else if (SmsDatabase.Types.isUnsupportedMessageType(type)) { + return emphasisAdded(context.getString(R.string.ThreadRecord_message_could_not_be_processed)); } else { if (TextUtils.isEmpty(getBody())) { return new SpannableString(emphasisAdded(context.getString(R.string.ThreadRecord_media_message))); diff --git a/src/org/thoughtcrime/securesms/jobs/PushDecryptJob.java b/src/org/thoughtcrime/securesms/jobs/PushDecryptJob.java index 86b292b997..986ba78f2b 100644 --- a/src/org/thoughtcrime/securesms/jobs/PushDecryptJob.java +++ b/src/org/thoughtcrime/securesms/jobs/PushDecryptJob.java @@ -117,6 +117,7 @@ import org.whispersystems.signalservice.api.messages.multidevice.StickerPackOper import org.whispersystems.signalservice.api.messages.multidevice.VerifiedMessage; import org.whispersystems.signalservice.api.messages.shared.SharedContact; import org.whispersystems.signalservice.api.push.SignalServiceAddress; +import org.whispersystems.signalservice.internal.push.UnsupportedDataMessageException; import java.security.MessageDigest; import java.security.SecureRandom; @@ -331,6 +332,9 @@ public class PushDecryptJob extends BaseJob { Log.w(TAG, e); } catch (SelfSendException e) { Log.i(TAG, "Dropping UD message from self."); + } catch (UnsupportedDataMessageException e) { + Log.w(TAG, e); + handleUnsupportedDataMessage(e.getSender(), e.getSenderDevice(), e.getGroup(), envelope.getTimestamp(), smsMessageId); } } @@ -1011,6 +1015,26 @@ public class PushDecryptJob extends BaseJob { } } + private void handleUnsupportedDataMessage(@NonNull String sender, + int senderDevice, + @NonNull Optional group, + long timestamp, + @NonNull Optional smsMessageId) + { + SmsDatabase smsDatabase = DatabaseFactory.getSmsDatabase(context); + + if (!smsMessageId.isPresent()) { + Optional insertResult = insertPlaceholder(sender, senderDevice, timestamp, group); + + if (insertResult.isPresent()) { + smsDatabase.markAsUnsupportedProtocolVersion(insertResult.get().getMessageId()); + MessageNotifier.updateNotification(context, insertResult.get().getThreadId()); + } + } else { + smsDatabase.markAsNoSession(smsMessageId.get()); + } + } + private void handleLegacyMessage(@NonNull String sender, int senderDevice, long timestamp, @NonNull Optional smsMessageId) { @@ -1241,10 +1265,14 @@ public class PushDecryptJob extends BaseJob { } private Optional insertPlaceholder(@NonNull String sender, int senderDevice, long timestamp) { + return insertPlaceholder(sender, senderDevice, timestamp, Optional.absent()); + } + + private Optional insertPlaceholder(@NonNull String sender, int senderDevice, long timestamp, Optional group) { SmsDatabase database = DatabaseFactory.getSmsDatabase(context); IncomingTextMessage textMessage = new IncomingTextMessage(Address.fromExternal(context, sender), senderDevice, timestamp, "", - Optional.absent(), 0, false); + group, 0, false); textMessage = new IncomingEncryptedMessage(textMessage, ""); return database.insertMessageInbox(textMessage);