From 4799c13816cb4345b1ea558ae29b702e331e6428 Mon Sep 17 00:00:00 2001 From: nielsandriesse Date: Wed, 8 Jul 2020 17:05:26 +1000 Subject: [PATCH 1/7] Clean up ahead of protocol changes --- .../securesms/ApplicationContext.java | 30 +++++++++---------- .../securesms/jobs/PushMediaSendJob.java | 6 ++-- .../securesms/jobs/PushTextSendJob.java | 6 ++-- .../loki/api/BackgroundPollWorker.kt | 6 ++-- .../loki/api/LokiPushNotificationManager.kt | 4 +-- .../loki/api/PushNotificationService.kt | 4 +-- .../loki/database/LokiAPIDatabase.kt | 28 ++++++++--------- .../dialogs/LinkDeviceMasterModeDialog.kt | 4 +-- .../loki/protocol/ClosedGroupsProtocol.kt | 2 +- .../loki/shelved/LokiRSSFeedPoller.kt | 4 +-- .../OptimizedMessageNotifier.java | 10 +++---- 11 files changed, 52 insertions(+), 52 deletions(-) diff --git a/src/org/thoughtcrime/securesms/ApplicationContext.java b/src/org/thoughtcrime/securesms/ApplicationContext.java index b9f0b87e0a..9c346f5a20 100644 --- a/src/org/thoughtcrime/securesms/ApplicationContext.java +++ b/src/org/thoughtcrime/securesms/ApplicationContext.java @@ -95,14 +95,14 @@ import org.whispersystems.libsignal.logging.SignalProtocolLoggerProvider; import org.whispersystems.signalservice.api.messages.SignalServiceEnvelope; import org.whispersystems.signalservice.api.util.StreamDetails; import org.whispersystems.signalservice.internal.push.SignalServiceProtos; -import org.whispersystems.signalservice.loki.api.LokiAPI; -import org.whispersystems.signalservice.loki.api.LokiPoller; -import org.whispersystems.signalservice.loki.api.LokiPushNotificationAcknowledgement; -import org.whispersystems.signalservice.loki.api.LokiSwarmAPI; +import org.whispersystems.signalservice.loki.api.Poller; +import org.whispersystems.signalservice.loki.api.PushNotificationAcknowledgement; +import org.whispersystems.signalservice.loki.api.SnodeAPI; +import org.whispersystems.signalservice.loki.api.SwarmAPI; import org.whispersystems.signalservice.loki.api.fileserver.LokiFileServerAPI; import org.whispersystems.signalservice.loki.api.opengroups.LokiPublicChatAPI; -import org.whispersystems.signalservice.loki.api.p2p.LokiP2PAPI; -import org.whispersystems.signalservice.loki.api.p2p.LokiP2PAPIDelegate; +import org.whispersystems.signalservice.loki.api.shelved.p2p.LokiP2PAPI; +import org.whispersystems.signalservice.loki.api.shelved.p2p.LokiP2PAPIDelegate; import org.whispersystems.signalservice.loki.database.LokiAPIDatabaseProtocol; import org.whispersystems.signalservice.loki.protocol.friendrequests.FriendRequestProtocol; import org.whispersystems.signalservice.loki.protocol.mentions.MentionsManager; @@ -151,7 +151,7 @@ public class ApplicationContext extends MultiDexApplication implements Dependenc // Loki public MessageNotifier messageNotifier = null; - public LokiPoller lokiPoller = null; + public Poller lokiPoller = null; public LokiPublicChatManager lokiPublicChatManager = null; private LokiPublicChatAPI lokiPublicChatAPI = null; public Broadcaster broadcaster = null; @@ -184,8 +184,8 @@ public class ApplicationContext extends MultiDexApplication implements Dependenc String userPublicKey = TextSecurePreferences.getLocalNumber(this); LokiSessionResetImplementation sessionResetImpl = new LokiSessionResetImplementation(this); if (userPublicKey != null) { - LokiSwarmAPI.Companion.configureIfNeeded(apiDB); - LokiAPI.Companion.configureIfNeeded(userPublicKey, apiDB, broadcaster); + SwarmAPI.Companion.configureIfNeeded(apiDB); + SnodeAPI.Companion.configureIfNeeded(userPublicKey, apiDB, broadcaster); FriendRequestProtocol.Companion.configureIfNeeded(apiDB, userPublicKey); MentionsManager.Companion.configureIfNeeded(userPublicKey, threadDB, userDB); SessionMetaProtocol.Companion.configureIfNeeded(apiDB, userPublicKey); @@ -194,7 +194,7 @@ public class ApplicationContext extends MultiDexApplication implements Dependenc MultiDeviceProtocol.Companion.configureIfNeeded(apiDB); SessionManagementProtocol.Companion.configureIfNeeded(sessionResetImpl, threadDB, this); setUpP2PAPIIfNeeded(); - LokiPushNotificationAcknowledgement.Companion.configureIfNeeded(BuildConfig.DEBUG); + PushNotificationAcknowledgement.Companion.configureIfNeeded(BuildConfig.DEBUG); if (setUpStorageAPIIfNeeded()) { if (userPublicKey != null) { Set deviceLinks = DatabaseFactory.getLokiAPIDatabase(this).getDeviceLinks(userPublicKey); @@ -493,15 +493,15 @@ public class ApplicationContext extends MultiDexApplication implements Dependenc String userPublicKey = TextSecurePreferences.getLocalNumber(this); if (userPublicKey == null) return; if (lokiPoller != null) { - LokiAPI.shared.setUserHexEncodedPublicKey(userPublicKey); - lokiPoller.setUserHexEncodedPublicKey(userPublicKey); + SnodeAPI.shared.setUserPublicKey(userPublicKey); + lokiPoller.setUserPublicKey(userPublicKey); return; } LokiAPIDatabase apiDB = DatabaseFactory.getLokiAPIDatabase(this); Context context = this; - LokiSwarmAPI.Companion.configureIfNeeded(apiDB); - LokiAPI.Companion.configureIfNeeded(userPublicKey, apiDB, broadcaster); - lokiPoller = new LokiPoller(userPublicKey, apiDB, protos -> { + SwarmAPI.Companion.configureIfNeeded(apiDB); + SnodeAPI.Companion.configureIfNeeded(userPublicKey, apiDB, broadcaster); + lokiPoller = new Poller(userPublicKey, apiDB, protos -> { for (SignalServiceProtos.Envelope proto : protos) { new PushContentReceiveJob(context).processEnvelope(new SignalServiceEnvelope(proto), false); } diff --git a/src/org/thoughtcrime/securesms/jobs/PushMediaSendJob.java b/src/org/thoughtcrime/securesms/jobs/PushMediaSendJob.java index 3779252021..d36fd517a5 100644 --- a/src/org/thoughtcrime/securesms/jobs/PushMediaSendJob.java +++ b/src/org/thoughtcrime/securesms/jobs/PushMediaSendJob.java @@ -44,7 +44,7 @@ import org.whispersystems.signalservice.api.messages.multidevice.SignalServiceSy import org.whispersystems.signalservice.api.messages.shared.SharedContact; import org.whispersystems.signalservice.api.push.SignalServiceAddress; import org.whispersystems.signalservice.api.push.exceptions.UnregisteredUserException; -import org.whispersystems.signalservice.loki.api.LokiAPI; +import org.whispersystems.signalservice.loki.api.SnodeAPI; import org.whispersystems.signalservice.loki.protocol.meta.SessionMetaProtocol; import java.io.FileNotFoundException; @@ -231,7 +231,7 @@ public class PushMediaSendJob extends PushSendJob implements InjectableType { database.addMismatchedIdentity(messageId, Address.fromSerialized(uie.getE164Number()), uie.getIdentityKey()); database.markAsSentFailed(messageId); } - } catch (LokiAPI.Error e) { + } catch (SnodeAPI.Error e) { Log.d("Loki", "Couldn't send message due to error: " + e.getDescription()); if (messageId >= 0) { LokiMessageDatabase lokiMessageDatabase = DatabaseFactory.getLokiMessageDatabase(context); @@ -257,7 +257,7 @@ public class PushMediaSendJob extends PushSendJob implements InjectableType { private boolean deliver(OutgoingMediaMessage message) throws RetryLaterException, InsecureFallbackApprovalException, UntrustedIdentityException, - UndeliverableMessageException, LokiAPI.Error + UndeliverableMessageException, SnodeAPI.Error { try { Recipient recipient = Recipient.from(context, destination, false); diff --git a/src/org/thoughtcrime/securesms/jobs/PushTextSendJob.java b/src/org/thoughtcrime/securesms/jobs/PushTextSendJob.java index fbb3a068b8..74f33f457f 100644 --- a/src/org/thoughtcrime/securesms/jobs/PushTextSendJob.java +++ b/src/org/thoughtcrime/securesms/jobs/PushTextSendJob.java @@ -32,7 +32,7 @@ import org.whispersystems.signalservice.api.messages.SignalServiceDataMessage; import org.whispersystems.signalservice.api.messages.multidevice.SignalServiceSyncMessage; import org.whispersystems.signalservice.api.push.SignalServiceAddress; import org.whispersystems.signalservice.api.push.exceptions.UnregisteredUserException; -import org.whispersystems.signalservice.loki.api.LokiAPI; +import org.whispersystems.signalservice.loki.api.SnodeAPI; import org.whispersystems.signalservice.loki.protocol.meta.SessionMetaProtocol; import java.io.IOException; @@ -173,7 +173,7 @@ public class PushTextSendJob extends PushSendJob implements InjectableType { database.markAsSentFailed(record.getId()); database.markAsPush(record.getId()); } - } catch (LokiAPI.Error e) { + } catch (SnodeAPI.Error e) { Log.d("Loki", "Couldn't send message due to error: " + e.getDescription()); if (messageId >= 0) { LokiMessageDatabase lokiMessageDatabase = DatabaseFactory.getLokiMessageDatabase(context); @@ -204,7 +204,7 @@ public class PushTextSendJob extends PushSendJob implements InjectableType { } private boolean deliver(SmsMessageRecord message) - throws UntrustedIdentityException, InsecureFallbackApprovalException, RetryLaterException, LokiAPI.Error + throws UntrustedIdentityException, InsecureFallbackApprovalException, RetryLaterException, SnodeAPI.Error { try { Recipient recipient = Recipient.from(context, destination, false); diff --git a/src/org/thoughtcrime/securesms/loki/api/BackgroundPollWorker.kt b/src/org/thoughtcrime/securesms/loki/api/BackgroundPollWorker.kt index 7265083dc5..8ae4cb0314 100644 --- a/src/org/thoughtcrime/securesms/loki/api/BackgroundPollWorker.kt +++ b/src/org/thoughtcrime/securesms/loki/api/BackgroundPollWorker.kt @@ -9,7 +9,7 @@ import org.thoughtcrime.securesms.jobs.PushContentReceiveJob import org.thoughtcrime.securesms.service.PersistentAlarmManagerListener import org.thoughtcrime.securesms.util.TextSecurePreferences import org.whispersystems.signalservice.api.messages.SignalServiceEnvelope -import org.whispersystems.signalservice.loki.api.LokiAPI +import org.whispersystems.signalservice.loki.api.SnodeAPI import java.util.concurrent.TimeUnit class BackgroundPollWorker : PersistentAlarmManagerListener() { @@ -35,8 +35,8 @@ class BackgroundPollWorker : PersistentAlarmManagerListener() { try { val applicationContext = context.applicationContext as ApplicationContext val broadcaster = applicationContext.broadcaster - LokiAPI.configureIfNeeded(userPublicKey, lokiAPIDatabase, broadcaster) - LokiAPI.shared.getMessages().map { messages -> + SnodeAPI.configureIfNeeded(userPublicKey, lokiAPIDatabase, broadcaster) + SnodeAPI.shared.getMessages().map { messages -> messages.forEach { PushContentReceiveJob(context).processEnvelope(SignalServiceEnvelope(it), false) } diff --git a/src/org/thoughtcrime/securesms/loki/api/LokiPushNotificationManager.kt b/src/org/thoughtcrime/securesms/loki/api/LokiPushNotificationManager.kt index 1180d0e68b..a51ed929bb 100644 --- a/src/org/thoughtcrime/securesms/loki/api/LokiPushNotificationManager.kt +++ b/src/org/thoughtcrime/securesms/loki/api/LokiPushNotificationManager.kt @@ -5,14 +5,14 @@ import okhttp3.* import org.thoughtcrime.securesms.util.TextSecurePreferences import org.whispersystems.libsignal.logging.Log import org.whispersystems.signalservice.internal.util.JsonUtil -import org.whispersystems.signalservice.loki.api.LokiPushNotificationAcknowledgement +import org.whispersystems.signalservice.loki.api.PushNotificationAcknowledgement import java.io.IOException object LokiPushNotificationManager { private val connection = OkHttpClient() private val server by lazy { - LokiPushNotificationAcknowledgement.shared.server + PushNotificationAcknowledgement.shared.server } private const val tokenExpirationInterval = 12 * 60 * 60 * 1000 diff --git a/src/org/thoughtcrime/securesms/loki/api/PushNotificationService.kt b/src/org/thoughtcrime/securesms/loki/api/PushNotificationService.kt index bdc55d10dc..0e2522b323 100644 --- a/src/org/thoughtcrime/securesms/loki/api/PushNotificationService.kt +++ b/src/org/thoughtcrime/securesms/loki/api/PushNotificationService.kt @@ -7,7 +7,7 @@ import org.thoughtcrime.securesms.util.TextSecurePreferences import org.whispersystems.libsignal.logging.Log import org.whispersystems.signalservice.api.messages.SignalServiceEnvelope import org.whispersystems.signalservice.internal.util.Base64 -import org.whispersystems.signalservice.loki.api.LokiMessageWrapper +import org.whispersystems.signalservice.loki.api.MessageWrapper class PushNotificationService : FirebaseMessagingService() { @@ -23,7 +23,7 @@ class PushNotificationService : FirebaseMessagingService() { val data = base64EncodedData?.let { Base64.decode(it) } if (data != null) { try { - val envelope = LokiMessageWrapper.unwrap(data) + val envelope = MessageWrapper.unwrap(data) PushContentReceiveJob(this).processEnvelope(SignalServiceEnvelope(envelope), true) } catch (e: Exception) { Log.d("Loki", "Failed to unwrap data for message.") diff --git a/src/org/thoughtcrime/securesms/loki/database/LokiAPIDatabase.kt b/src/org/thoughtcrime/securesms/loki/database/LokiAPIDatabase.kt index 5f953a4b7b..ca55870188 100644 --- a/src/org/thoughtcrime/securesms/loki/database/LokiAPIDatabase.kt +++ b/src/org/thoughtcrime/securesms/loki/database/LokiAPIDatabase.kt @@ -8,7 +8,7 @@ import org.thoughtcrime.securesms.database.helpers.SQLCipherOpenHelper import org.thoughtcrime.securesms.loki.utilities.* import org.thoughtcrime.securesms.util.Base64 import org.thoughtcrime.securesms.util.TextSecurePreferences -import org.whispersystems.signalservice.loki.api.LokiAPITarget +import org.whispersystems.signalservice.loki.api.Snode import org.whispersystems.signalservice.loki.database.LokiAPIDatabaseProtocol import org.whispersystems.signalservice.loki.protocol.multidevice.DeviceLink @@ -77,7 +77,7 @@ class LokiAPIDatabase(context: Context, helper: SQLCipherOpenHelper) : Database( @JvmStatic val createSessionRequestTimestampCacheCommand = "CREATE TABLE $sessionRequestTimestampCache ($publicKey STRING PRIMARY KEY, $timestamp INTEGER DEFAULT 0);" } - override fun getSnodePool(): Set { + override fun getSnodePool(): Set { val database = databaseHelper.readableDatabase return database.get(snodePoolCache, "${Companion.dummyKey} = ?", wrap("dummy_key")) { cursor -> val snodePoolAsString = cursor.getString(cursor.getColumnIndexOrThrow(snodePool)) @@ -87,12 +87,12 @@ class LokiAPIDatabase(context: Context, helper: SQLCipherOpenHelper) : Database( val port = components.getOrNull(1)?.toIntOrNull() ?: return@mapNotNull null val ed25519Key = components.getOrNull(2) ?: return@mapNotNull null val x25519Key = components.getOrNull(3) ?: return@mapNotNull null - LokiAPITarget(address, port, LokiAPITarget.KeySet(ed25519Key, x25519Key)) + Snode(address, port, Snode.KeySet(ed25519Key, x25519Key)) } }?.toSet() ?: setOf() } - override fun setSnodePool(newValue: Set) { + override fun setSnodePool(newValue: Set) { val database = databaseHelper.writableDatabase val snodePoolAsString = newValue.joinToString(", ") { snode -> var string = "${snode.address}-${snode.port}" @@ -106,9 +106,9 @@ class LokiAPIDatabase(context: Context, helper: SQLCipherOpenHelper) : Database( database.insertOrUpdate(snodePoolCache, row, "${Companion.dummyKey} = ?", wrap("dummy_key")) } - override fun getOnionRequestPaths(): List> { + override fun getOnionRequestPaths(): List> { val database = databaseHelper.readableDatabase - fun get(indexPath: String): LokiAPITarget? { + fun get(indexPath: String): Snode? { return database.get(onionRequestPathCache, "${Companion.indexPath} = ?", wrap(indexPath)) { cursor -> val snodeAsString = cursor.getString(cursor.getColumnIndexOrThrow(snode)) val components = snodeAsString.split("-") @@ -117,7 +117,7 @@ class LokiAPIDatabase(context: Context, helper: SQLCipherOpenHelper) : Database( val ed25519Key = components.getOrNull(2) val x25519Key = components.getOrNull(3) if (port != null && ed25519Key != null && x25519Key != null) { - LokiAPITarget(address, port, LokiAPITarget.KeySet(ed25519Key, x25519Key)) + Snode(address, port, Snode.KeySet(ed25519Key, x25519Key)) } else { null } @@ -139,7 +139,7 @@ class LokiAPIDatabase(context: Context, helper: SQLCipherOpenHelper) : Database( delete("1-1"); delete("1-2") } - override fun setOnionRequestPaths(newValue: List>) { + override fun setOnionRequestPaths(newValue: List>) { // FIXME: This is a bit of a dirty approach that assumes 2 paths of length 3 each. We should do better than this. if (newValue.count() != 2) { return } val path0 = newValue[0] @@ -147,7 +147,7 @@ class LokiAPIDatabase(context: Context, helper: SQLCipherOpenHelper) : Database( if (path0.count() != 3 || path1.count() != 3) { return } Log.d("Loki", "Persisting onion request paths to database.") val database = databaseHelper.writableDatabase - fun set(indexPath: String ,snode: LokiAPITarget) { + fun set(indexPath: String ,snode: Snode) { var snodeAsString = "${snode.address}-${snode.port}" val keySet = snode.publicKeySet if (keySet != null) { @@ -161,7 +161,7 @@ class LokiAPIDatabase(context: Context, helper: SQLCipherOpenHelper) : Database( set("1-1", path1[1]); set("1-2", path1[2]) } - override fun getSwarm(hexEncodedPublicKey: String): Set? { + override fun getSwarm(hexEncodedPublicKey: String): Set? { val database = databaseHelper.readableDatabase return database.get(swarmCache, "${Companion.hexEncodedPublicKey} = ?", wrap(hexEncodedPublicKey)) { cursor -> val swarmAsString = cursor.getString(cursor.getColumnIndexOrThrow(swarm)) @@ -171,12 +171,12 @@ class LokiAPIDatabase(context: Context, helper: SQLCipherOpenHelper) : Database( val port = components.getOrNull(1)?.toIntOrNull() ?: return@mapNotNull null val ed25519Key = components.getOrNull(2) ?: return@mapNotNull null val x25519Key = components.getOrNull(3) ?: return@mapNotNull null - LokiAPITarget(address, port, LokiAPITarget.KeySet(ed25519Key, x25519Key)) + Snode(address, port, Snode.KeySet(ed25519Key, x25519Key)) } }?.toSet() } - override fun setSwarm(hexEncodedPublicKey: String, newValue: Set) { + override fun setSwarm(hexEncodedPublicKey: String, newValue: Set) { val database = databaseHelper.writableDatabase val swarmAsString = newValue.joinToString(", ") { target -> var string = "${target.address}-${target.port}" @@ -190,14 +190,14 @@ class LokiAPIDatabase(context: Context, helper: SQLCipherOpenHelper) : Database( database.insertOrUpdate(swarmCache, row, "${Companion.hexEncodedPublicKey} = ?", wrap(hexEncodedPublicKey)) } - override fun getLastMessageHashValue(target: LokiAPITarget): String? { + override fun getLastMessageHashValue(target: Snode): String? { val database = databaseHelper.readableDatabase return database.get(lastMessageHashValueCache, "${Companion.target} = ?", wrap(target.address)) { cursor -> cursor.getString(cursor.getColumnIndexOrThrow(lastMessageHashValue)) } } - override fun setLastMessageHashValue(target: LokiAPITarget, newValue: String) { + override fun setLastMessageHashValue(target: Snode, newValue: String) { val database = databaseHelper.writableDatabase val row = wrap(mapOf(Companion.target to target.address, lastMessageHashValue to newValue)) database.insertOrUpdate(lastMessageHashValueCache, row, "${Companion.target} = ?", wrap(target.address)) diff --git a/src/org/thoughtcrime/securesms/loki/dialogs/LinkDeviceMasterModeDialog.kt b/src/org/thoughtcrime/securesms/loki/dialogs/LinkDeviceMasterModeDialog.kt index ab899c717c..019160b674 100644 --- a/src/org/thoughtcrime/securesms/loki/dialogs/LinkDeviceMasterModeDialog.kt +++ b/src/org/thoughtcrime/securesms/loki/dialogs/LinkDeviceMasterModeDialog.kt @@ -21,7 +21,7 @@ import org.thoughtcrime.securesms.loki.utilities.QRCodeUtilities import org.thoughtcrime.securesms.loki.utilities.toPx import org.thoughtcrime.securesms.util.TextSecurePreferences import org.thoughtcrime.securesms.util.Util -import org.whispersystems.signalservice.loki.api.LokiAPI +import org.whispersystems.signalservice.loki.api.SnodeAPI import org.whispersystems.signalservice.loki.api.fileserver.LokiFileServerAPI import org.whispersystems.signalservice.loki.crypto.MnemonicCodec import org.whispersystems.signalservice.loki.protocol.multidevice.DeviceLink @@ -84,7 +84,7 @@ class LinkDeviceMasterModeDialog : DialogFragment(), DeviceLinkingSessionListene contentView.cancelButton.visibility = View.GONE contentView.authorizeButton.visibility = View.GONE } - LokiFileServerAPI.shared.addDeviceLink(deviceLink).bind(LokiAPI.sharedContext) { + LokiFileServerAPI.shared.addDeviceLink(deviceLink).bind(SnodeAPI.sharedContext) { MultiDeviceProtocol.signAndSendDeviceLinkMessage(context!!, deviceLink) }.success { TextSecurePreferences.setMultiDevice(context!!, true) diff --git a/src/org/thoughtcrime/securesms/loki/protocol/ClosedGroupsProtocol.kt b/src/org/thoughtcrime/securesms/loki/protocol/ClosedGroupsProtocol.kt index f18ddab0cf..8e7e84111c 100644 --- a/src/org/thoughtcrime/securesms/loki/protocol/ClosedGroupsProtocol.kt +++ b/src/org/thoughtcrime/securesms/loki/protocol/ClosedGroupsProtocol.kt @@ -17,7 +17,7 @@ import org.whispersystems.libsignal.SignalProtocolAddress import org.whispersystems.signalservice.api.messages.SignalServiceContent import org.whispersystems.signalservice.api.messages.SignalServiceGroup import org.whispersystems.signalservice.api.push.SignalServiceAddress -import org.whispersystems.signalservice.loki.api.LokiAPI +import org.whispersystems.signalservice.loki.api.SnodeAPI import org.whispersystems.signalservice.loki.api.fileserver.LokiFileServerAPI import org.whispersystems.signalservice.loki.protocol.multidevice.MultiDeviceProtocol import java.util.* diff --git a/src/org/thoughtcrime/securesms/loki/shelved/LokiRSSFeedPoller.kt b/src/org/thoughtcrime/securesms/loki/shelved/LokiRSSFeedPoller.kt index 18e3c6e307..7096629119 100644 --- a/src/org/thoughtcrime/securesms/loki/shelved/LokiRSSFeedPoller.kt +++ b/src/org/thoughtcrime/securesms/loki/shelved/LokiRSSFeedPoller.kt @@ -14,8 +14,8 @@ import org.whispersystems.signalservice.api.messages.SignalServiceContent import org.whispersystems.signalservice.api.messages.SignalServiceDataMessage import org.whispersystems.signalservice.api.messages.SignalServiceGroup import org.whispersystems.signalservice.api.push.SignalServiceAddress -import org.whispersystems.signalservice.loki.api.rssfeeds.LokiRSSFeed -import org.whispersystems.signalservice.loki.api.rssfeeds.LokiRSSFeedProxy +import org.whispersystems.signalservice.loki.api.shelved.rssfeeds.LokiRSSFeed +import org.whispersystems.signalservice.loki.api.shelved.rssfeeds.LokiRSSFeedProxy import java.text.SimpleDateFormat import java.util.regex.Pattern diff --git a/src/org/thoughtcrime/securesms/notifications/OptimizedMessageNotifier.java b/src/org/thoughtcrime/securesms/notifications/OptimizedMessageNotifier.java index 46e718359a..0a6d1af2c7 100644 --- a/src/org/thoughtcrime/securesms/notifications/OptimizedMessageNotifier.java +++ b/src/org/thoughtcrime/securesms/notifications/OptimizedMessageNotifier.java @@ -9,7 +9,7 @@ import org.thoughtcrime.securesms.ApplicationContext; import org.thoughtcrime.securesms.loki.api.LokiPublicChatManager; import org.thoughtcrime.securesms.recipients.Recipient; import org.thoughtcrime.securesms.util.Debouncer; -import org.whispersystems.signalservice.loki.api.LokiPoller; +import org.whispersystems.signalservice.loki.api.Poller; import java.util.concurrent.TimeUnit; @@ -39,7 +39,7 @@ public class OptimizedMessageNotifier implements MessageNotifier { @Override public void updateNotification(@NonNull Context context) { - LokiPoller lokiPoller = ApplicationContext.getInstance(context).lokiPoller; + Poller lokiPoller = ApplicationContext.getInstance(context).lokiPoller; LokiPublicChatManager lokiPublicChatManager = ApplicationContext.getInstance(context).lokiPublicChatManager; Boolean isCaughtUp = false; if (lokiPoller != null && lokiPublicChatManager != null) { @@ -55,7 +55,7 @@ public class OptimizedMessageNotifier implements MessageNotifier { @Override public void updateNotification(@NonNull Context context, long threadId) { - LokiPoller lokiPoller = ApplicationContext.getInstance(context).lokiPoller; + Poller lokiPoller = ApplicationContext.getInstance(context).lokiPoller; LokiPublicChatManager lokiPublicChatManager = ApplicationContext.getInstance(context).lokiPublicChatManager; Boolean isCaughtUp = false; if (lokiPoller != null && lokiPublicChatManager != null) { @@ -71,7 +71,7 @@ public class OptimizedMessageNotifier implements MessageNotifier { @Override public void updateNotification(@NonNull Context context, long threadId, boolean signal) { - LokiPoller lokiPoller = ApplicationContext.getInstance(context).lokiPoller; + Poller lokiPoller = ApplicationContext.getInstance(context).lokiPoller; LokiPublicChatManager lokiPublicChatManager = ApplicationContext.getInstance(context).lokiPublicChatManager; Boolean isCaughtUp = false; if (lokiPoller != null && lokiPublicChatManager != null) { @@ -87,7 +87,7 @@ public class OptimizedMessageNotifier implements MessageNotifier { @Override public void updateNotification(@android.support.annotation.NonNull Context context, boolean signal, int reminderCount) { - LokiPoller lokiPoller = ApplicationContext.getInstance(context).lokiPoller; + Poller lokiPoller = ApplicationContext.getInstance(context).lokiPoller; LokiPublicChatManager lokiPublicChatManager = ApplicationContext.getInstance(context).lokiPublicChatManager; Boolean isCaughtUp = false; if (lokiPoller != null && lokiPublicChatManager != null) { From 5a64e1cf3a3911f553b0b12091ba0cf539ed9301 Mon Sep 17 00:00:00 2001 From: nielsandriesse Date: Fri, 10 Jul 2020 09:46:14 +1000 Subject: [PATCH 2/7] Make session handling logic consistent with desktop --- .../securesms/ApplicationContext.java | 15 +++++++++++++++ .../loki/protocol/ClosedGroupsProtocol.kt | 8 +------- .../loki/protocol/SessionManagementProtocol.kt | 18 ++++++++++++++---- 3 files changed, 30 insertions(+), 11 deletions(-) diff --git a/src/org/thoughtcrime/securesms/ApplicationContext.java b/src/org/thoughtcrime/securesms/ApplicationContext.java index 9c346f5a20..c83193444d 100644 --- a/src/org/thoughtcrime/securesms/ApplicationContext.java +++ b/src/org/thoughtcrime/securesms/ApplicationContext.java @@ -38,6 +38,7 @@ import org.thoughtcrime.securesms.components.TypingStatusSender; import org.thoughtcrime.securesms.crypto.IdentityKeyUtil; import org.thoughtcrime.securesms.crypto.MasterSecretUtil; import org.thoughtcrime.securesms.crypto.ProfileKeyUtil; +import org.thoughtcrime.securesms.crypto.storage.TextSecureSessionStore; import org.thoughtcrime.securesms.database.Address; import org.thoughtcrime.securesms.database.DatabaseFactory; import org.thoughtcrime.securesms.dependencies.AxolotlStorageModule; @@ -91,8 +92,10 @@ import org.webrtc.PeerConnectionFactory; import org.webrtc.PeerConnectionFactory.InitializationOptions; import org.webrtc.voiceengine.WebRtcAudioManager; import org.webrtc.voiceengine.WebRtcAudioUtils; +import org.whispersystems.libsignal.SignalProtocolAddress; import org.whispersystems.libsignal.logging.SignalProtocolLoggerProvider; import org.whispersystems.signalservice.api.messages.SignalServiceEnvelope; +import org.whispersystems.signalservice.api.push.SignalServiceAddress; import org.whispersystems.signalservice.api.util.StreamDetails; import org.whispersystems.signalservice.internal.push.SignalServiceProtos; import org.whispersystems.signalservice.loki.api.Poller; @@ -588,6 +591,18 @@ public class ApplicationContext extends MultiDexApplication implements Dependenc @Override public void sendSessionRequest(@NotNull String publicKey) { + // It's never necessary to establish a session with self + String userPublicKey = TextSecurePreferences.getLocalNumber(this); + if (publicKey.equals(userPublicKey)) { return; } + // Check that we don't already have a session + SignalProtocolAddress address = new SignalProtocolAddress(publicKey, SignalServiceAddress.DEFAULT_DEVICE_ID); + boolean hasSession = new TextSecureSessionStore(this).containsSession(address); + if (hasSession) { return; } + // Check that we didn't already send or process a session request + LokiAPIDatabase apiDB = DatabaseFactory.getLokiAPIDatabase(this); + boolean hasSentOrProcessedSessionRequest = (apiDB.getSessionRequestTimestamp(publicKey) != null); + if (hasSentOrProcessedSessionRequest) { return; } + // Send the session request DatabaseFactory.getLokiAPIDatabase(this).setSessionRequestTimestamp(publicKey, new Date().getTime()); EphemeralMessage sessionRequest = EphemeralMessage.createSessionRequest(publicKey); jobManager.add(new PushEphemeralMessageSendJob(sessionRequest)); diff --git a/src/org/thoughtcrime/securesms/loki/protocol/ClosedGroupsProtocol.kt b/src/org/thoughtcrime/securesms/loki/protocol/ClosedGroupsProtocol.kt index 8e7e84111c..40311e35cf 100644 --- a/src/org/thoughtcrime/securesms/loki/protocol/ClosedGroupsProtocol.kt +++ b/src/org/thoughtcrime/securesms/loki/protocol/ClosedGroupsProtocol.kt @@ -106,13 +106,7 @@ object ClosedGroupsProtocol { allDevices.remove(userPublicKey) } for (device in allDevices) { - val deviceAsAddress = SignalProtocolAddress(device, SignalServiceAddress.DEFAULT_DEVICE_ID) - val hasSession = TextSecureSessionStore(context).containsSession(deviceAsAddress) - if (hasSession) { continue } - if (DatabaseFactory.getLokiAPIDatabase(context).getSessionRequestTimestamp(device) != null) { return } - DatabaseFactory.getLokiAPIDatabase(context).setSessionRequestTimestamp(device, Date().time) - val sessionRequest = EphemeralMessage.createSessionRequest(device) - ApplicationContext.getInstance(context).jobManager.add(PushEphemeralMessageSendJob(sessionRequest)) + ApplicationContext.getInstance(context).sendSessionRequest(device) } } } \ No newline at end of file diff --git a/src/org/thoughtcrime/securesms/loki/protocol/SessionManagementProtocol.kt b/src/org/thoughtcrime/securesms/loki/protocol/SessionManagementProtocol.kt index 81ca56eaa0..be4663ba4e 100644 --- a/src/org/thoughtcrime/securesms/loki/protocol/SessionManagementProtocol.kt +++ b/src/org/thoughtcrime/securesms/loki/protocol/SessionManagementProtocol.kt @@ -16,7 +16,7 @@ import org.thoughtcrime.securesms.util.TextSecurePreferences import org.whispersystems.libsignal.loki.LokiSessionResetStatus import org.whispersystems.signalservice.api.messages.SignalServiceContent import org.whispersystems.signalservice.loki.protocol.multidevice.MultiDeviceProtocol -import org.whispersystems.signalservice.loki.protocol.todo.LokiThreadFriendRequestStatus +import java.util.* object SessionManagementProtocol { @@ -59,6 +59,14 @@ object SessionManagementProtocol { val registrationID = TextSecurePreferences.getLocalRegistrationId(context) // TODO: It seems wrong to use the local registration ID for this? val lokiPreKeyBundleDatabase = DatabaseFactory.getLokiPreKeyBundleDatabase(context) Log.d("Loki", "Received a pre key bundle from: " + content.sender.toString() + ".") + if (content.dataMessage.isPresent && content.dataMessage.get().isSessionRequest) { + val sessionRequestTimestamp = DatabaseFactory.getLokiAPIDatabase(context).getSessionRequestTimestamp(content.sender) + if (sessionRequestTimestamp != null && content.timestamp < sessionRequestTimestamp) { + // We sent or processed a session request after this one was sent + Log.d("Loki", "Ignoring session request from: ${content.sender}.") + return + } + } val preKeyBundle = preKeyBundleMessage.getPreKeyBundle(registrationID) lokiPreKeyBundleDatabase.setPreKeyBundle(content.sender, preKeyBundle) } @@ -66,11 +74,13 @@ object SessionManagementProtocol { @JvmStatic fun handleSessionRequestIfNeeded(context: Context, content: SignalServiceContent): Boolean { if (!content.dataMessage.isPresent || !content.dataMessage.get().isSessionRequest) { return false } - val sentSessionRequestTimestamp = DatabaseFactory.getLokiAPIDatabase(context).getSessionRequestTimestamp(content.sender) - if (sentSessionRequestTimestamp != null && content.timestamp < sentSessionRequestTimestamp) { - // We sent a session request after this one was sent + val sessionRequestTimestamp = DatabaseFactory.getLokiAPIDatabase(context).getSessionRequestTimestamp(content.sender) + if (sessionRequestTimestamp != null && content.timestamp < sessionRequestTimestamp) { + // We sent or processed a session request after this one was sent + Log.d("Loki", "Ignoring session request from: ${content.sender}.") return false } + DatabaseFactory.getLokiAPIDatabase(context).setSessionRequestTimestamp(content.sender, Date().time) val ephemeralMessage = EphemeralMessage.create(content.sender) ApplicationContext.getInstance(context).jobManager.add(PushEphemeralMessageSendJob(ephemeralMessage)) return true From b3351d7297e2338ad8288bff9387875e58e51041 Mon Sep 17 00:00:00 2001 From: nielsandriesse Date: Fri, 10 Jul 2020 11:09:00 +1000 Subject: [PATCH 3/7] Update for desktop protocol changes --- .../securesms/jobs/PushDecryptJob.java | 70 ++++++---------- .../loki/protocol/PushNullMessageSendJob.kt | 84 +++++++++++++++++++ 2 files changed, 110 insertions(+), 44 deletions(-) create mode 100644 src/org/thoughtcrime/securesms/loki/protocol/PushNullMessageSendJob.kt diff --git a/src/org/thoughtcrime/securesms/jobs/PushDecryptJob.java b/src/org/thoughtcrime/securesms/jobs/PushDecryptJob.java index 3a5a0be5df..04e7b50762 100644 --- a/src/org/thoughtcrime/securesms/jobs/PushDecryptJob.java +++ b/src/org/thoughtcrime/securesms/jobs/PushDecryptJob.java @@ -73,6 +73,7 @@ import org.thoughtcrime.securesms.loki.protocol.FriendRequestProtocol; import org.thoughtcrime.securesms.loki.protocol.LokiSessionResetImplementation; import org.thoughtcrime.securesms.loki.protocol.MultiDeviceProtocol; import org.thoughtcrime.securesms.loki.protocol.PushEphemeralMessageSendJob; +import org.thoughtcrime.securesms.loki.protocol.PushNullMessageSendJob; import org.thoughtcrime.securesms.loki.protocol.SessionManagementProtocol; import org.thoughtcrime.securesms.loki.protocol.SessionMetaProtocol; import org.thoughtcrime.securesms.loki.protocol.SyncMessagesProtocol; @@ -162,7 +163,6 @@ public class PushDecryptJob extends BaseJob implements InjectableType { private MessageNotifier messageNotifier; @Inject SignalServiceMessageSender messageSender; - private Address author; public PushDecryptJob(Context context) { this(context, -1); @@ -316,51 +316,13 @@ public class PushDecryptJob extends BaseJob implements InjectableType { } else if (isMediaMessage) { handleMediaMessage(content, message, smsMessageId, Optional.absent()); - // Loki - This is needed for compatibility with refactored desktop clients - if (!message.isGroupMessage()) { - Recipient recipient = recipient(context, content.getSender()); - long threadID = DatabaseFactory.getThreadDatabase(context).getThreadIdFor(recipient); - LokiThreadDatabase threadDB = DatabaseFactory.getLokiThreadDatabase(context); - LokiThreadFriendRequestStatus threadFriendRequestStatus = threadDB.getFriendRequestStatus(threadID); - if (threadFriendRequestStatus == LokiThreadFriendRequestStatus.NONE || threadFriendRequestStatus == LokiThreadFriendRequestStatus.REQUEST_EXPIRED) { - threadDB.setFriendRequestStatus(threadID, LokiThreadFriendRequestStatus.REQUEST_RECEIVED); - } else if (threadFriendRequestStatus == LokiThreadFriendRequestStatus.REQUEST_SENT) { - threadDB.setFriendRequestStatus(threadID, LokiThreadFriendRequestStatus.FRIENDS); - EphemeralMessage ephemeralMessage = EphemeralMessage.create(content.getSender()); - ApplicationContext.getInstance(context).getJobManager().add(new PushEphemeralMessageSendJob(ephemeralMessage)); - SyncMessagesProtocol.syncContact(context, Address.fromSerialized(content.getSender())); - } - - // Loki - Handle friend request message if needed - FriendRequestProtocol.handleFriendRequestMessageIfNeeded(context, content.getSender(), content); - } + // Loki - Handle friend request message if needed + FriendRequestProtocol.handleFriendRequestMessageIfNeeded(context, content.getSender(), content); } else if (message.getBody().isPresent()) { handleTextMessage(content, message, smsMessageId, Optional.absent()); - // Loki - This is needed for compatibility with refactored desktop clients - if (!message.isGroupMessage()) { - Recipient recipient = recipient(context, content.getSender()); - long threadID = DatabaseFactory.getThreadDatabase(context).getThreadIdFor(recipient); - LokiThreadDatabase threadDB = DatabaseFactory.getLokiThreadDatabase(context); - LokiThreadFriendRequestStatus threadFriendRequestStatus = threadDB.getFriendRequestStatus(threadID); - if (threadFriendRequestStatus == LokiThreadFriendRequestStatus.NONE || threadFriendRequestStatus == LokiThreadFriendRequestStatus.REQUEST_EXPIRED) { - threadDB.setFriendRequestStatus(threadID, LokiThreadFriendRequestStatus.REQUEST_RECEIVED); - } else if (threadFriendRequestStatus == LokiThreadFriendRequestStatus.REQUEST_SENT) { - threadDB.setFriendRequestStatus(threadID, LokiThreadFriendRequestStatus.FRIENDS); - EphemeralMessage ephemeralMessage = EphemeralMessage.create(content.getSender()); - ApplicationContext.getInstance(context).getJobManager().add(new PushEphemeralMessageSendJob(ephemeralMessage)); - SyncMessagesProtocol.syncContact(context, Address.fromSerialized(content.getSender())); - } - - // Loki - Handle friend request message if needed - FriendRequestProtocol.handleFriendRequestMessageIfNeeded(context, content.getSender(), content); - } - } else { - // Loki - This is needed for compatibility with refactored desktop clients - if (envelope.isFriendRequest()) { - EphemeralMessage ephemeralMessage = EphemeralMessage.create(content.getSender()); - ApplicationContext.getInstance(context).getJobManager().add(new PushEphemeralMessageSendJob(ephemeralMessage)); - } + // Loki - Handle friend request message if needed + FriendRequestProtocol.handleFriendRequestMessageIfNeeded(context, content.getSender(), content); } if (message.getGroupInfo().isPresent() && groupDatabase.isUnknownGroup(GroupUtil.getEncodedId(message.getGroupInfo().get()))) { @@ -406,7 +368,27 @@ public class PushDecryptJob extends BaseJob implements InjectableType { } else if (content.getTypingMessage().isPresent()) { handleTypingMessage(content, content.getTypingMessage().get()); } else { - Log.w(TAG, "Got unrecognized message..."); + + // Loki - This is needed for compatibility with refactored desktop clients + // ======== + if (envelope.isFriendRequest()) { + ApplicationContext.getInstance(context).getJobManager().add(new PushNullMessageSendJob(content.getSender())); + } else { + Log.w(TAG, "Got unrecognized message..."); + } + Recipient recipient = recipient(context, content.getSender()); + long threadID = DatabaseFactory.getThreadDatabase(context).getThreadIdFor(recipient); + LokiThreadDatabase threadDB = DatabaseFactory.getLokiThreadDatabase(context); + LokiThreadFriendRequestStatus threadFriendRequestStatus = threadDB.getFriendRequestStatus(threadID); + if (threadFriendRequestStatus == LokiThreadFriendRequestStatus.NONE || threadFriendRequestStatus == LokiThreadFriendRequestStatus.REQUEST_EXPIRED) { + threadDB.setFriendRequestStatus(threadID, LokiThreadFriendRequestStatus.REQUEST_RECEIVED); + } else if (threadFriendRequestStatus == LokiThreadFriendRequestStatus.REQUEST_SENT) { + threadDB.setFriendRequestStatus(threadID, LokiThreadFriendRequestStatus.FRIENDS); + EphemeralMessage ephemeralMessage = EphemeralMessage.create(content.getSender()); + ApplicationContext.getInstance(context).getJobManager().add(new PushEphemeralMessageSendJob(ephemeralMessage)); + SyncMessagesProtocol.syncContact(context, Address.fromSerialized(content.getSender())); + } + // ======== } resetRecipientToPush(Recipient.from(context, Address.fromSerialized(content.getSender()), false)); diff --git a/src/org/thoughtcrime/securesms/loki/protocol/PushNullMessageSendJob.kt b/src/org/thoughtcrime/securesms/loki/protocol/PushNullMessageSendJob.kt new file mode 100644 index 0000000000..a0e745b626 --- /dev/null +++ b/src/org/thoughtcrime/securesms/loki/protocol/PushNullMessageSendJob.kt @@ -0,0 +1,84 @@ +package org.thoughtcrime.securesms.loki.protocol + +import com.google.protobuf.ByteString +import org.thoughtcrime.securesms.ApplicationContext +import org.thoughtcrime.securesms.crypto.UnidentifiedAccessUtil +import org.thoughtcrime.securesms.database.Address +import org.thoughtcrime.securesms.jobmanager.Data +import org.thoughtcrime.securesms.jobmanager.Job +import org.thoughtcrime.securesms.jobmanager.impl.NetworkConstraint +import org.thoughtcrime.securesms.jobs.BaseJob +import org.thoughtcrime.securesms.logging.Log +import org.thoughtcrime.securesms.recipients.Recipient +import org.whispersystems.signalservice.api.push.SignalServiceAddress +import org.whispersystems.signalservice.internal.push.SignalServiceProtos +import org.whispersystems.signalservice.loki.protocol.meta.TTLUtilities +import java.io.IOException +import java.security.SecureRandom +import java.util.* +import java.util.concurrent.TimeUnit + +class PushNullMessageSendJob private constructor(parameters: Parameters, private val publicKey: String) : BaseJob(parameters) { + + companion object { + const val KEY = "PushNullMessageSendJob" + } + + constructor(publicKey: String) : this(Parameters.Builder() + .addConstraint(NetworkConstraint.KEY) + .setQueue(KEY) + .setLifespan(TimeUnit.DAYS.toMillis(1)) + .setMaxAttempts(1) + .build(), + publicKey) + + override fun serialize(): Data { + return Data.Builder().putString("publicKey", publicKey).build() + } + + override fun getFactoryKey(): String { return KEY } + + public override fun onRun() { + val contentMessage = SignalServiceProtos.Content.newBuilder() + val nullMessage = SignalServiceProtos.NullMessage.newBuilder() + val sr = SecureRandom() + val paddingSize = sr.nextInt(512) + val padding = ByteArray(paddingSize) + sr.nextBytes(padding) + nullMessage.padding = ByteString.copyFrom(padding) + contentMessage.nullMessage = nullMessage.build() + val serializedContentMessage = contentMessage.build().toByteArray() + val messageSender = ApplicationContext.getInstance(context).communicationModule.provideSignalMessageSender() + val address = SignalServiceAddress(publicKey) + val recipient = Recipient.from(context, Address.fromSerialized(publicKey), false) + val udAccess = UnidentifiedAccessUtil.getAccessFor(context, recipient) + val ttl = TTLUtilities.getTTL(TTLUtilities.MessageType.Ephemeral) + try { + messageSender.sendMessage(0, address, udAccess.get().targetUnidentifiedAccess, + Date().time, serializedContentMessage, false, ttl, false, + false, false, false, false) + } catch (e: Exception) { + Log.d("Loki", "Failed to send null message to: $publicKey due to error: $e.") + throw e + } + } + + public override fun onShouldRetry(e: Exception): Boolean { + // Disable since we have our own retrying + return false + } + + override fun onCanceled() { } + + class Factory : Job.Factory { + + override fun create(parameters: Parameters, data: Data): PushNullMessageSendJob { + try { + val publicKey = data.getString("publicKey") + return PushNullMessageSendJob(parameters, publicKey) + } catch (e: IOException) { + throw AssertionError(e) + } + } + } +} From bfb260ef53f68393aee8bae18a9b0ef9f4ea43ab Mon Sep 17 00:00:00 2001 From: nielsandriesse Date: Fri, 10 Jul 2020 11:43:45 +1000 Subject: [PATCH 4/7] Add debug assertions --- .../OptimizedMessageNotifier.java | 23 +++++++++++++++---- 1 file changed, 19 insertions(+), 4 deletions(-) diff --git a/src/org/thoughtcrime/securesms/notifications/OptimizedMessageNotifier.java b/src/org/thoughtcrime/securesms/notifications/OptimizedMessageNotifier.java index 0a6d1af2c7..94c63deebd 100644 --- a/src/org/thoughtcrime/securesms/notifications/OptimizedMessageNotifier.java +++ b/src/org/thoughtcrime/securesms/notifications/OptimizedMessageNotifier.java @@ -1,6 +1,7 @@ package org.thoughtcrime.securesms.notifications; import android.content.Context; +import android.os.Looper; import androidx.annotation.MainThread; import androidx.annotation.NonNull; @@ -13,6 +14,8 @@ import org.whispersystems.signalservice.loki.api.Poller; import java.util.concurrent.TimeUnit; +import network.loki.messenger.BuildConfig; + public class OptimizedMessageNotifier implements MessageNotifier { private final MessageNotifier wrapped; private final Debouncer debouncer; @@ -39,9 +42,12 @@ public class OptimizedMessageNotifier implements MessageNotifier { @Override public void updateNotification(@NonNull Context context) { + if (BuildConfig.DEBUG && Looper.myLooper() != Looper.getMainLooper()) { + throw new AssertionError(); + } Poller lokiPoller = ApplicationContext.getInstance(context).lokiPoller; LokiPublicChatManager lokiPublicChatManager = ApplicationContext.getInstance(context).lokiPublicChatManager; - Boolean isCaughtUp = false; + boolean isCaughtUp = false; if (lokiPoller != null && lokiPublicChatManager != null) { isCaughtUp = lokiPoller.isCaughtUp() && lokiPublicChatManager.areAllCaughtUp(); } @@ -55,9 +61,12 @@ public class OptimizedMessageNotifier implements MessageNotifier { @Override public void updateNotification(@NonNull Context context, long threadId) { + if (BuildConfig.DEBUG && Looper.myLooper() != Looper.getMainLooper()) { + throw new AssertionError(); + } Poller lokiPoller = ApplicationContext.getInstance(context).lokiPoller; LokiPublicChatManager lokiPublicChatManager = ApplicationContext.getInstance(context).lokiPublicChatManager; - Boolean isCaughtUp = false; + boolean isCaughtUp = false; if (lokiPoller != null && lokiPublicChatManager != null) { isCaughtUp = lokiPoller.isCaughtUp() && lokiPublicChatManager.areAllCaughtUp(); } @@ -71,9 +80,12 @@ public class OptimizedMessageNotifier implements MessageNotifier { @Override public void updateNotification(@NonNull Context context, long threadId, boolean signal) { + if (BuildConfig.DEBUG && Looper.myLooper() != Looper.getMainLooper()) { + throw new AssertionError(); + } Poller lokiPoller = ApplicationContext.getInstance(context).lokiPoller; LokiPublicChatManager lokiPublicChatManager = ApplicationContext.getInstance(context).lokiPublicChatManager; - Boolean isCaughtUp = false; + boolean isCaughtUp = false; if (lokiPoller != null && lokiPublicChatManager != null) { isCaughtUp = lokiPoller.isCaughtUp() && lokiPublicChatManager.areAllCaughtUp(); } @@ -87,9 +99,12 @@ public class OptimizedMessageNotifier implements MessageNotifier { @Override public void updateNotification(@android.support.annotation.NonNull Context context, boolean signal, int reminderCount) { + if (BuildConfig.DEBUG && Looper.myLooper() != Looper.getMainLooper()) { + throw new AssertionError(); + } Poller lokiPoller = ApplicationContext.getInstance(context).lokiPoller; LokiPublicChatManager lokiPublicChatManager = ApplicationContext.getInstance(context).lokiPublicChatManager; - Boolean isCaughtUp = false; + boolean isCaughtUp = false; if (lokiPoller != null && lokiPublicChatManager != null) { isCaughtUp = lokiPoller.isCaughtUp() && lokiPublicChatManager.areAllCaughtUp(); } From 69bcfe6c020a9f7581eebdc2267b94e9c1f06c5d Mon Sep 17 00:00:00 2001 From: Mikunj Date: Fri, 10 Jul 2020 13:39:05 +1000 Subject: [PATCH 5/7] Minor fixes --- .../jobmanager/migration/WorkManagerFactoryMappings.java | 2 ++ src/org/thoughtcrime/securesms/jobs/JobManagerFactories.java | 2 ++ src/org/thoughtcrime/securesms/jobs/PushDecryptJob.java | 2 +- .../thoughtcrime/securesms/loki/api/LokiPublicChatPoller.kt | 4 ++-- .../thoughtcrime/securesms/loki/shelved/LokiRSSFeedPoller.kt | 2 +- 5 files changed, 8 insertions(+), 4 deletions(-) diff --git a/src/org/thoughtcrime/securesms/jobmanager/migration/WorkManagerFactoryMappings.java b/src/org/thoughtcrime/securesms/jobmanager/migration/WorkManagerFactoryMappings.java index da6e221978..c4aa802414 100644 --- a/src/org/thoughtcrime/securesms/jobmanager/migration/WorkManagerFactoryMappings.java +++ b/src/org/thoughtcrime/securesms/jobmanager/migration/WorkManagerFactoryMappings.java @@ -44,6 +44,7 @@ import org.thoughtcrime.securesms.jobs.SmsSentJob; import org.thoughtcrime.securesms.jobs.TrimThreadJob; import org.thoughtcrime.securesms.jobs.TypingSendJob; import org.thoughtcrime.securesms.jobs.UpdateApkJob; +import org.thoughtcrime.securesms.loki.protocol.PushNullMessageSendJob; import java.util.HashMap; import java.util.Map; @@ -74,6 +75,7 @@ public class WorkManagerFactoryMappings { put(PushMediaSendJob.class.getName(), PushMediaSendJob.KEY); put(PushNotificationReceiveJob.class.getName(), PushNotificationReceiveJob.KEY); put(PushTextSendJob.class.getName(), PushTextSendJob.KEY); + put(PushNullMessageSendJob.class.getName(), PushNullMessageSendJob.KEY); put(RefreshAttributesJob.class.getName(), RefreshAttributesJob.KEY); put(RefreshPreKeysJob.class.getName(), RefreshPreKeysJob.KEY); put(RefreshUnidentifiedDeliveryAbilityJob.class.getName(), RefreshUnidentifiedDeliveryAbilityJob.KEY); diff --git a/src/org/thoughtcrime/securesms/jobs/JobManagerFactories.java b/src/org/thoughtcrime/securesms/jobs/JobManagerFactories.java index a366bafe8c..c1c869e920 100644 --- a/src/org/thoughtcrime/securesms/jobs/JobManagerFactories.java +++ b/src/org/thoughtcrime/securesms/jobs/JobManagerFactories.java @@ -15,6 +15,7 @@ import org.thoughtcrime.securesms.jobmanager.impl.SqlCipherMigrationConstraint; import org.thoughtcrime.securesms.jobmanager.impl.SqlCipherMigrationConstraintObserver; import org.thoughtcrime.securesms.loki.protocol.MultiDeviceOpenGroupUpdateJob; import org.thoughtcrime.securesms.loki.protocol.PushEphemeralMessageSendJob; +import org.thoughtcrime.securesms.loki.protocol.PushNullMessageSendJob; import java.util.Arrays; import java.util.HashMap; @@ -50,6 +51,7 @@ public final class JobManagerFactories { put(PushMediaSendJob.KEY, new PushMediaSendJob.Factory()); put(PushNotificationReceiveJob.KEY, new PushNotificationReceiveJob.Factory()); put(PushTextSendJob.KEY, new PushTextSendJob.Factory()); + put(PushNullMessageSendJob.KEY, new PushNullMessageSendJob.Factory()); put(RefreshAttributesJob.KEY, new RefreshAttributesJob.Factory()); put(RefreshPreKeysJob.KEY, new RefreshPreKeysJob.Factory()); put(RefreshUnidentifiedDeliveryAbilityJob.KEY, new RefreshUnidentifiedDeliveryAbilityJob.Factory()); diff --git a/src/org/thoughtcrime/securesms/jobs/PushDecryptJob.java b/src/org/thoughtcrime/securesms/jobs/PushDecryptJob.java index 04e7b50762..824dc11ec7 100644 --- a/src/org/thoughtcrime/securesms/jobs/PushDecryptJob.java +++ b/src/org/thoughtcrime/securesms/jobs/PushDecryptJob.java @@ -371,7 +371,7 @@ public class PushDecryptJob extends BaseJob implements InjectableType { // Loki - This is needed for compatibility with refactored desktop clients // ======== - if (envelope.isFriendRequest()) { + if (content.isFriendRequest()) { ApplicationContext.getInstance(context).getJobManager().add(new PushNullMessageSendJob(content.getSender())); } else { Log.w(TAG, "Got unrecognized message..."); diff --git a/src/org/thoughtcrime/securesms/loki/api/LokiPublicChatPoller.kt b/src/org/thoughtcrime/securesms/loki/api/LokiPublicChatPoller.kt index 17770c77a4..3389bb100e 100644 --- a/src/org/thoughtcrime/securesms/loki/api/LokiPublicChatPoller.kt +++ b/src/org/thoughtcrime/securesms/loki/api/LokiPublicChatPoller.kt @@ -34,7 +34,7 @@ import java.util.* class LokiPublicChatPoller(private val context: Context, private val group: LokiPublicChat) { private val handler = Handler() private var hasStarted = false - public var isCaughtUp = false + var isCaughtUp = false // region Convenience private val userHexEncodedPublicKey = TextSecurePreferences.getLocalNumber(context) @@ -166,7 +166,7 @@ class LokiPublicChatPoller(private val context: Context, private val group: Loki } val senderHexEncodedPublicKey = masterHexEncodedPublicKey ?: message.hexEncodedPublicKey val serviceDataMessage = getDataMessage(message) - val serviceContent = SignalServiceContent(serviceDataMessage, senderHexEncodedPublicKey, SignalServiceAddress.DEFAULT_DEVICE_ID, message.timestamp, false, false, false, false, false) + val serviceContent = SignalServiceContent(serviceDataMessage, senderHexEncodedPublicKey, SignalServiceAddress.DEFAULT_DEVICE_ID, message.timestamp, false, false, false, false) if (serviceDataMessage.quote.isPresent || (serviceDataMessage.attachments.isPresent && serviceDataMessage.attachments.get().size > 0) || serviceDataMessage.previews.isPresent) { PushDecryptJob(context).handleMediaMessage(serviceContent, serviceDataMessage, Optional.absent(), Optional.of(message.serverID)) } else { diff --git a/src/org/thoughtcrime/securesms/loki/shelved/LokiRSSFeedPoller.kt b/src/org/thoughtcrime/securesms/loki/shelved/LokiRSSFeedPoller.kt index 7096629119..de10a226fe 100644 --- a/src/org/thoughtcrime/securesms/loki/shelved/LokiRSSFeedPoller.kt +++ b/src/org/thoughtcrime/securesms/loki/shelved/LokiRSSFeedPoller.kt @@ -66,7 +66,7 @@ class LokiRSSFeedPoller(private val context: Context, private val feed: LokiRSSF val id = feed.id.toByteArray() val x1 = SignalServiceGroup(SignalServiceGroup.Type.UPDATE, id, SignalServiceGroup.GroupType.RSS_FEED, null, null, null, null) val x2 = SignalServiceDataMessage(timestamp, x1, null, body) - val x3 = SignalServiceContent(x2, "Loki", SignalServiceAddress.DEFAULT_DEVICE_ID, timestamp, false, false, false, false, false) + val x3 = SignalServiceContent(x2, "Loki", SignalServiceAddress.DEFAULT_DEVICE_ID, timestamp, false, false, false, false) PushDecryptJob(context).handleTextMessage(x3, x2, Optional.absent(), Optional.absent()) } }.fail { exception -> From 7afb763576f407d17d0dd48271d918708818fce4 Mon Sep 17 00:00:00 2001 From: nielsandriesse Date: Fri, 10 Jul 2020 14:00:04 +1000 Subject: [PATCH 6/7] Maintain code style consistency --- src/org/thoughtcrime/securesms/loki/api/LokiPublicChatPoller.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/org/thoughtcrime/securesms/loki/api/LokiPublicChatPoller.kt b/src/org/thoughtcrime/securesms/loki/api/LokiPublicChatPoller.kt index 3389bb100e..bc521e86ba 100644 --- a/src/org/thoughtcrime/securesms/loki/api/LokiPublicChatPoller.kt +++ b/src/org/thoughtcrime/securesms/loki/api/LokiPublicChatPoller.kt @@ -34,7 +34,7 @@ import java.util.* class LokiPublicChatPoller(private val context: Context, private val group: LokiPublicChat) { private val handler = Handler() private var hasStarted = false - var isCaughtUp = false + public var isCaughtUp = false // region Convenience private val userHexEncodedPublicKey = TextSecurePreferences.getLocalNumber(context) From bc71bf50aa5bcbe10c06a89e5c77ebc06bb8bb5c Mon Sep 17 00:00:00 2001 From: nielsandriesse Date: Fri, 10 Jul 2020 15:19:12 +1000 Subject: [PATCH 7/7] Fix crash & friend request handling bug --- .../OptimizedMessageNotifier.java | 38 ++++++++----------- 1 file changed, 16 insertions(+), 22 deletions(-) diff --git a/src/org/thoughtcrime/securesms/notifications/OptimizedMessageNotifier.java b/src/org/thoughtcrime/securesms/notifications/OptimizedMessageNotifier.java index 94c63deebd..3b335f9909 100644 --- a/src/org/thoughtcrime/securesms/notifications/OptimizedMessageNotifier.java +++ b/src/org/thoughtcrime/securesms/notifications/OptimizedMessageNotifier.java @@ -14,8 +14,6 @@ import org.whispersystems.signalservice.loki.api.Poller; import java.util.concurrent.TimeUnit; -import network.loki.messenger.BuildConfig; - public class OptimizedMessageNotifier implements MessageNotifier { private final MessageNotifier wrapped; private final Debouncer debouncer; @@ -42,9 +40,6 @@ public class OptimizedMessageNotifier implements MessageNotifier { @Override public void updateNotification(@NonNull Context context) { - if (BuildConfig.DEBUG && Looper.myLooper() != Looper.getMainLooper()) { - throw new AssertionError(); - } Poller lokiPoller = ApplicationContext.getInstance(context).lokiPoller; LokiPublicChatManager lokiPublicChatManager = ApplicationContext.getInstance(context).lokiPublicChatManager; boolean isCaughtUp = false; @@ -53,17 +48,14 @@ public class OptimizedMessageNotifier implements MessageNotifier { } if (isCaughtUp) { - wrapped.updateNotification(context); + performOnBackgroundThreadIfNeeded(() -> wrapped.updateNotification(context)); } else { - debouncer.publish(() -> wrapped.updateNotification(context)); + debouncer.publish(() -> performOnBackgroundThreadIfNeeded(() -> wrapped.updateNotification(context))); } } @Override public void updateNotification(@NonNull Context context, long threadId) { - if (BuildConfig.DEBUG && Looper.myLooper() != Looper.getMainLooper()) { - throw new AssertionError(); - } Poller lokiPoller = ApplicationContext.getInstance(context).lokiPoller; LokiPublicChatManager lokiPublicChatManager = ApplicationContext.getInstance(context).lokiPublicChatManager; boolean isCaughtUp = false; @@ -72,17 +64,14 @@ public class OptimizedMessageNotifier implements MessageNotifier { } if (isCaughtUp) { - wrapped.updateNotification(context, threadId); + performOnBackgroundThreadIfNeeded(() -> wrapped.updateNotification(context, threadId)); } else { - debouncer.publish(() -> wrapped.updateNotification(context, threadId)); + debouncer.publish(() -> performOnBackgroundThreadIfNeeded(() -> wrapped.updateNotification(context, threadId))); } } @Override public void updateNotification(@NonNull Context context, long threadId, boolean signal) { - if (BuildConfig.DEBUG && Looper.myLooper() != Looper.getMainLooper()) { - throw new AssertionError(); - } Poller lokiPoller = ApplicationContext.getInstance(context).lokiPoller; LokiPublicChatManager lokiPublicChatManager = ApplicationContext.getInstance(context).lokiPublicChatManager; boolean isCaughtUp = false; @@ -91,17 +80,14 @@ public class OptimizedMessageNotifier implements MessageNotifier { } if (isCaughtUp) { - wrapped.updateNotification(context, threadId, signal); + performOnBackgroundThreadIfNeeded(() -> wrapped.updateNotification(context, threadId, signal)); } else { - debouncer.publish(() -> wrapped.updateNotification(context, threadId, signal)); + debouncer.publish(() -> performOnBackgroundThreadIfNeeded(() -> wrapped.updateNotification(context, threadId, signal))); } } @Override public void updateNotification(@android.support.annotation.NonNull Context context, boolean signal, int reminderCount) { - if (BuildConfig.DEBUG && Looper.myLooper() != Looper.getMainLooper()) { - throw new AssertionError(); - } Poller lokiPoller = ApplicationContext.getInstance(context).lokiPoller; LokiPublicChatManager lokiPublicChatManager = ApplicationContext.getInstance(context).lokiPublicChatManager; boolean isCaughtUp = false; @@ -110,12 +96,20 @@ public class OptimizedMessageNotifier implements MessageNotifier { } if (isCaughtUp) { - wrapped.updateNotification(context, signal, reminderCount); + performOnBackgroundThreadIfNeeded(() -> wrapped.updateNotification(context, signal, reminderCount)); } else { - debouncer.publish(() -> wrapped.updateNotification(context, signal, reminderCount)); + debouncer.publish(() -> performOnBackgroundThreadIfNeeded(() -> wrapped.updateNotification(context, signal, reminderCount))); } } @Override public void clearReminder(@NonNull Context context) { wrapped.clearReminder(context); } + + private void performOnBackgroundThreadIfNeeded(Runnable r) { + if (Looper.myLooper() == Looper.getMainLooper()) { + new Thread(r).start(); + } else { + r.run(); + } + } }