From cf49bf81fc69d6354c2f95f72c4e40b19bae3851 Mon Sep 17 00:00:00 2001 From: Ryan ZHAO Date: Wed, 2 Sep 2020 14:44:15 +1000 Subject: [PATCH 1/3] fix missing messages in open groups --- src/org/thoughtcrime/securesms/jobs/PushDecryptJob.java | 5 ++++- .../thoughtcrime/securesms/loki/api/PublicChatPoller.kt | 9 ++++++--- .../securesms/loki/protocol/SessionMetaProtocol.kt | 3 +-- 3 files changed, 11 insertions(+), 6 deletions(-) diff --git a/src/org/thoughtcrime/securesms/jobs/PushDecryptJob.java b/src/org/thoughtcrime/securesms/jobs/PushDecryptJob.java index 4b97762c9b..69ce6a08a6 100644 --- a/src/org/thoughtcrime/securesms/jobs/PushDecryptJob.java +++ b/src/org/thoughtcrime/securesms/jobs/PushDecryptJob.java @@ -834,6 +834,8 @@ public class PushDecryptJob extends BaseJob implements InjectableType { public long handleSynchronizeSentMediaMessage(@NonNull SentTranscriptMessage message) throws MmsException { + if (SessionMetaProtocol.shouldIgnoreMessage(message.getTimestamp())) { return -1; } + MmsDatabase database = DatabaseFactory.getMmsDatabase(context); Recipient recipients = getSyncMessageMasterDestination(message); Optional quote = getValidatedQuote(message.getMessage().getQuote()); @@ -1002,6 +1004,7 @@ public class PushDecryptJob extends BaseJob implements InjectableType { public long handleSynchronizeSentTextMessage(@NonNull SentTranscriptMessage message) throws MmsException { + if (SessionMetaProtocol.shouldIgnoreMessage(message.getTimestamp())) { return -1; } Recipient recipient = getSyncMessageMasterDestination(message); String body = message.getMessage().getBody().or(""); @@ -1459,7 +1462,7 @@ public class PushDecryptJob extends BaseJob implements InjectableType { return true; } - if (SessionMetaProtocol.shouldIgnoreMessage(content)) { + if (SessionMetaProtocol.shouldIgnoreMessage(content.getTimestamp())) { Log.d("Loki", "Ignoring duplicate message."); return true; } diff --git a/src/org/thoughtcrime/securesms/loki/api/PublicChatPoller.kt b/src/org/thoughtcrime/securesms/loki/api/PublicChatPoller.kt index 6a5ee5dad0..049a991aa8 100644 --- a/src/org/thoughtcrime/securesms/loki/api/PublicChatPoller.kt +++ b/src/org/thoughtcrime/securesms/loki/api/PublicChatPoller.kt @@ -34,6 +34,7 @@ import java.util.* class PublicChatPoller(private val context: Context, private val group: PublicChat) { private val handler = Handler() private var hasStarted = false + private var isPolling = false public var isCaughtUp = false // region Convenience @@ -186,12 +187,10 @@ class PublicChatPoller(private val context: Context, private val group: PublicCh } fun processOutgoingMessage(message: PublicChatMessage) { val messageServerID = message.serverID ?: return - val isDuplicate = DatabaseFactory.getLokiMessageDatabase(context).getMessageID(messageServerID) != null - if (isDuplicate) { return } if (message.body.isEmpty() && message.attachments.isEmpty() && message.quote == null) { return } val userHexEncodedPublicKey = TextSecurePreferences.getLocalNumber(context) val dataMessage = getDataMessage(message) - SessionMetaProtocol.dropFromTimestampCacheIfNeeded(dataMessage.timestamp) + SessionMetaProtocol.dropFromTimestampCacheIfNeeded(message.serverTimestamp) val transcript = SentTranscriptMessage(userHexEncodedPublicKey, message.serverTimestamp, dataMessage, dataMessage.expiresInSeconds.toLong(), Collections.singletonMap(userHexEncodedPublicKey, false)) transcript.messageServerID = messageServerID if (dataMessage.quote.isPresent || (dataMessage.attachments.isPresent && dataMessage.attachments.get().size > 0) || dataMessage.previews.isPresent) { @@ -212,6 +211,8 @@ class PublicChatPoller(private val context: Context, private val group: PublicCh } } } + if (isPolling) { return } + isPolling = true val userDevices = MultiDeviceProtocol.shared.getAllLinkedDevices(userHexEncodedPublicKey) var uniqueDevices = setOf() val userPrivateKey = IdentityKeyUtil.getIdentityKeyPair(context).privateKey.serialize() @@ -249,8 +250,10 @@ class PublicChatPoller(private val context: Context, private val group: PublicCh } } isCaughtUp = true + isPolling = false }.fail { Log.d("Loki", "Failed to get messages for group chat with ID: ${group.channel} on server: ${group.server}.") + isPolling = false } } diff --git a/src/org/thoughtcrime/securesms/loki/protocol/SessionMetaProtocol.kt b/src/org/thoughtcrime/securesms/loki/protocol/SessionMetaProtocol.kt index b4a16ed505..c3322f9a08 100644 --- a/src/org/thoughtcrime/securesms/loki/protocol/SessionMetaProtocol.kt +++ b/src/org/thoughtcrime/securesms/loki/protocol/SessionMetaProtocol.kt @@ -23,8 +23,7 @@ object SessionMetaProtocol { } @JvmStatic - fun shouldIgnoreMessage(content: SignalServiceContent): Boolean { - val timestamp = content.timestamp + fun shouldIgnoreMessage(timestamp: Long): Boolean { val shouldIgnoreMessage = timestamps.contains(timestamp) timestamps.add(timestamp) return shouldIgnoreMessage From 906deb3adae8c9d483b8379e1a769f3d69f39a9d Mon Sep 17 00:00:00 2001 From: nielsandriesse Date: Wed, 2 Sep 2020 16:03:23 +1000 Subject: [PATCH 2/3] Add copy Session ID button for one-to-one chats --- res/menu/conversation_copy_session_id.xml | 8 ++++++++ res/values/strings.xml | 2 ++ .../conversation/ConversationActivity.java | 13 +++++++++++++ 3 files changed, 23 insertions(+) create mode 100644 res/menu/conversation_copy_session_id.xml diff --git a/res/menu/conversation_copy_session_id.xml b/res/menu/conversation_copy_session_id.xml new file mode 100644 index 0000000000..e74d0b4c24 --- /dev/null +++ b/res/menu/conversation_copy_session_id.xml @@ -0,0 +1,8 @@ + + + + + + \ No newline at end of file diff --git a/res/values/strings.xml b/res/values/strings.xml index 4a2b5ca5e3..37828d83af 100644 --- a/res/values/strings.xml +++ b/res/values/strings.xml @@ -1855,4 +1855,6 @@ Secure session reset done + Copy Session ID + diff --git a/src/org/thoughtcrime/securesms/conversation/ConversationActivity.java b/src/org/thoughtcrime/securesms/conversation/ConversationActivity.java index 5beff5770f..db705b4f14 100644 --- a/src/org/thoughtcrime/securesms/conversation/ConversationActivity.java +++ b/src/org/thoughtcrime/securesms/conversation/ConversationActivity.java @@ -22,6 +22,8 @@ import android.annotation.TargetApi; import androidx.lifecycle.ViewModelProviders; import android.content.ActivityNotFoundException; import android.content.BroadcastReceiver; +import android.content.ClipData; +import android.content.ClipboardManager; import android.content.Context; import android.content.Intent; import android.content.IntentFilter; @@ -760,6 +762,7 @@ public class ConversationActivity extends PassphraseRequiredActionBarActivity } else { inflater.inflate(R.menu.conversation_block, menu); } + inflater.inflate(R.menu.conversation_copy_session_id, menu); } else if (isGroupConversation() && !isOpenGroupOrRSSFeed) { // inflater.inflate(R.menu.conversation_group_options, menu); @@ -867,6 +870,7 @@ public class ConversationActivity extends PassphraseRequiredActionBarActivity case R.id.menu_call_insecure: handleDial(getRecipient(), false); return true; case R.id.menu_unblock: handleUnblock(); return true; case R.id.menu_block: handleBlock(); return true; + case R.id.menu_copy_session_id: handleCopySessionID(); return true; case R.id.menu_view_media: handleViewMedia(); return true; case R.id.menu_add_shortcut: handleAddShortcut(); return true; case R.id.menu_search: handleSearch(); return true; @@ -1096,6 +1100,15 @@ public class ConversationActivity extends PassphraseRequiredActionBarActivity }).show(); } + private void handleCopySessionID() { + if (recipient.isGroupRecipient()) { return; } + String sessionID = recipient.getAddress().toPhoneString(); + ClipboardManager clipboard = (ClipboardManager)getSystemService(Context.CLIPBOARD_SERVICE); + ClipData clip = ClipData.newPlainText("Session ID", sessionID); + clipboard.setPrimaryClip(clip); + Toast.makeText(this, R.string.copied_to_clipboard, Toast.LENGTH_SHORT).show(); + } + private void handleViewMedia() { Intent intent = new Intent(this, MediaOverviewActivity.class); intent.putExtra(MediaOverviewActivity.ADDRESS_EXTRA, recipient.getAddress()); From 837ca48cde8b5eaabe2a3eee1cc829c08d785afc Mon Sep 17 00:00:00 2001 From: nielsandriesse Date: Wed, 2 Sep 2020 16:14:57 +1000 Subject: [PATCH 3/3] Minor refactoring --- .../securesms/loki/api/PublicChatPoller.kt | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/src/org/thoughtcrime/securesms/loki/api/PublicChatPoller.kt b/src/org/thoughtcrime/securesms/loki/api/PublicChatPoller.kt index 049a991aa8..80b52c533e 100644 --- a/src/org/thoughtcrime/securesms/loki/api/PublicChatPoller.kt +++ b/src/org/thoughtcrime/securesms/loki/api/PublicChatPoller.kt @@ -5,7 +5,6 @@ import android.os.Handler import android.util.Log import nl.komponents.kovenant.Promise import nl.komponents.kovenant.functional.bind -import nl.komponents.kovenant.then import org.thoughtcrime.securesms.ApplicationContext import org.thoughtcrime.securesms.crypto.IdentityKeyUtil import org.thoughtcrime.securesms.database.Address @@ -34,7 +33,7 @@ import java.util.* class PublicChatPoller(private val context: Context, private val group: PublicChat) { private val handler = Handler() private var hasStarted = false - private var isPolling = false + private var isPollOngoing = false public var isCaughtUp = false // region Convenience @@ -211,8 +210,8 @@ class PublicChatPoller(private val context: Context, private val group: PublicCh } } } - if (isPolling) { return } - isPolling = true + if (isPollOngoing) { return } + isPollOngoing = true val userDevices = MultiDeviceProtocol.shared.getAllLinkedDevices(userHexEncodedPublicKey) var uniqueDevices = setOf() val userPrivateKey = IdentityKeyUtil.getIdentityKeyPair(context).privateKey.serialize() @@ -250,10 +249,10 @@ class PublicChatPoller(private val context: Context, private val group: PublicCh } } isCaughtUp = true - isPolling = false + isPollOngoing = false }.fail { Log.d("Loki", "Failed to get messages for group chat with ID: ${group.channel} on server: ${group.server}.") - isPolling = false + isPollOngoing = false } }