diff --git a/src/org/thoughtcrime/securesms/ApplicationContext.java b/src/org/thoughtcrime/securesms/ApplicationContext.java index 614019ced9..4771324407 100644 --- a/src/org/thoughtcrime/securesms/ApplicationContext.java +++ b/src/org/thoughtcrime/securesms/ApplicationContext.java @@ -152,7 +152,7 @@ public class ApplicationContext extends MultiDexApplication implements Dependenc // Loki public MessageNotifier messageNotifier = null; - public Poller lokiPoller = null; + public Poller poller = null; public PublicChatManager publicChatManager = null; private PublicChatAPI publicChatAPI = null; public Broadcaster broadcaster = null; @@ -226,7 +226,7 @@ public class ApplicationContext extends MultiDexApplication implements Dependenc executePendingContactSync(); KeyCachingService.onAppForegrounded(this); // Loki - if (lokiPoller != null) { lokiPoller.setCaughtUp(false); } + if (poller != null) { poller.setCaughtUp(false); } startPollingIfNeeded(); publicChatManager.markAllAsNotCaughtUp(); publicChatManager.startPollersIfNeeded(); @@ -239,7 +239,7 @@ public class ApplicationContext extends MultiDexApplication implements Dependenc KeyCachingService.onAppBackgrounded(this); messageNotifier.setVisibleThread(-1); // Loki - if (lokiPoller != null) { lokiPoller.stopIfNeeded(); } + if (poller != null) { poller.stopIfNeeded(); } if (publicChatManager != null) { publicChatManager.stopPollers(); } } @@ -491,16 +491,16 @@ public class ApplicationContext extends MultiDexApplication implements Dependenc private void setUpPollingIfNeeded() { String userPublicKey = TextSecurePreferences.getLocalNumber(this); if (userPublicKey == null) return; - if (lokiPoller != null) { + if (poller != null) { SnodeAPI.shared.setUserPublicKey(userPublicKey); - lokiPoller.setUserPublicKey(userPublicKey); + poller.setUserPublicKey(userPublicKey); return; } LokiAPIDatabase apiDB = DatabaseFactory.getLokiAPIDatabase(this); Context context = this; SwarmAPI.Companion.configureIfNeeded(apiDB); SnodeAPI.Companion.configureIfNeeded(userPublicKey, apiDB, broadcaster); - lokiPoller = new Poller(userPublicKey, apiDB, protos -> { + poller = new Poller(userPublicKey, apiDB, protos -> { for (SignalServiceProtos.Envelope proto : protos) { new PushContentReceiveJob(context).processEnvelope(new SignalServiceEnvelope(proto), false); } @@ -510,12 +510,12 @@ public class ApplicationContext extends MultiDexApplication implements Dependenc public void startPollingIfNeeded() { setUpPollingIfNeeded(); - if (lokiPoller != null) { lokiPoller.startIfNeeded(); } + if (poller != null) { poller.startIfNeeded(); } } public void stopPolling() { - if (lokiPoller == null) { return; } - lokiPoller.stopIfNeeded(); + if (poller == null) { return; } + poller.stopIfNeeded(); } private void resubmitProfilePictureIfNeeded() { diff --git a/src/org/thoughtcrime/securesms/jobs/PushDecryptJob.java b/src/org/thoughtcrime/securesms/jobs/PushDecryptJob.java index 8d75a599b5..4ceb4009f8 100644 --- a/src/org/thoughtcrime/securesms/jobs/PushDecryptJob.java +++ b/src/org/thoughtcrime/securesms/jobs/PushDecryptJob.java @@ -48,7 +48,6 @@ import org.thoughtcrime.securesms.database.MessagingDatabase.SyncMessageId; import org.thoughtcrime.securesms.database.MmsDatabase; import org.thoughtcrime.securesms.database.NoSuchMessageException; import org.thoughtcrime.securesms.database.PushDatabase; -import org.thoughtcrime.securesms.database.RecipientDatabase; import org.thoughtcrime.securesms.database.SmsDatabase; import org.thoughtcrime.securesms.database.StickerDatabase; import org.thoughtcrime.securesms.database.ThreadDatabase; @@ -68,7 +67,6 @@ import org.thoughtcrime.securesms.loki.activities.HomeActivity; import org.thoughtcrime.securesms.loki.database.LokiMessageDatabase; import org.thoughtcrime.securesms.loki.protocol.ClosedGroupsProtocol; import org.thoughtcrime.securesms.loki.protocol.MultiDeviceProtocol; -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.SessionResetImplementation; @@ -129,7 +127,6 @@ import org.whispersystems.signalservice.loki.crypto.LokiServiceCipher; import org.whispersystems.signalservice.loki.protocol.mentions.MentionsManager; import org.whispersystems.signalservice.loki.utilities.PublicKeyValidation; -import java.security.MessageDigest; import java.security.SecureRandom; import java.util.ArrayList; import java.util.Collections; @@ -298,7 +295,7 @@ public class PushDecryptJob extends BaseJob implements InjectableType { } if (message.getProfileKey().isPresent() && message.getProfileKey().get().length == 32) { - handleProfileKey(content, message); + SessionMetaProtocol.handleProfileKeyUpdate(context, content); } if (content.isNeedsReceipt()) { @@ -335,12 +332,8 @@ public class PushDecryptJob extends BaseJob implements InjectableType { else if (message.isDeliveryReceipt()) handleDeliveryReceipt(content, message); } else if (content.getTypingMessage().isPresent()) { handleTypingMessage(content, content.getTypingMessage().get()); - } else if (content.getNullMessage().isPresent()) { - if (content.preKeyBundleMessage.isPresent()) { - ApplicationContext.getInstance(context).getJobManager().add(new PushNullMessageSendJob(content.getSender())); - } else { - Log.w(TAG, "Got unrecognized message..."); - } + } else { + Log.w(TAG, "Got unrecognized message..."); } resetRecipientToPush(Recipient.from(context, Address.fromSerialized(content.getSender()), false)); @@ -637,7 +630,7 @@ public class PushDecryptJob extends BaseJob implements InjectableType { DatabaseFactory.getRecipientDatabase(context).setProfileSharing(recipient, true); } - handleProfileKey(content, message.getMessage()); + SessionMetaProtocol.handleProfileKeyUpdate(context, content); } SessionMetaProtocol.handleProfileUpdateIfNeeded(context, content); @@ -781,20 +774,28 @@ public class PushDecryptJob extends BaseJob implements InjectableType { messageNotifier.updateNotification(context, insertResult.get().getThreadId()); } - // Loki - Store message open group server ID if needed - if (insertResult.isPresent() && messageServerIDOrNull.isPresent()) { - long messageID = insertResult.get().getMessageId(); - long messageServerID = messageServerIDOrNull.get(); - LokiMessageDatabase lokiMessageDatabase = DatabaseFactory.getLokiMessageDatabase(context); - lokiMessageDatabase.setServerID(messageID, messageServerID); - } - - // Loki - Update mapping of message ID to original thread ID if (insertResult.isPresent()) { - ThreadDatabase threadDatabase = DatabaseFactory.getThreadDatabase(context); - LokiMessageDatabase lokiMessageDatabase = DatabaseFactory.getLokiMessageDatabase(context); - long originalThreadId = threadDatabase.getThreadIdFor(originalRecipient); - lokiMessageDatabase.setOriginalThreadID(insertResult.get().getMessageId(), originalThreadId); + InsertResult result = insertResult.get(); + + // Loki - Cache the user hex encoded public key (for mentions) + MentionManagerUtilities.INSTANCE.populateUserPublicKeyCacheIfNeeded(result.getThreadId(), context); + MentionsManager.shared.cache(content.getSender(), result.getThreadId()); + + // Loki - Store message open group server ID if needed + if (messageServerIDOrNull.isPresent()) { + long messageID = result.getMessageId(); + long messageServerID = messageServerIDOrNull.get(); + LokiMessageDatabase lokiMessageDatabase = DatabaseFactory.getLokiMessageDatabase(context); + lokiMessageDatabase.setServerID(messageID, messageServerID); + } + + // Loki - Update mapping of message ID to original thread ID + if (result.getMessageId() > -1) { + ThreadDatabase threadDatabase = DatabaseFactory.getThreadDatabase(context); + LokiMessageDatabase lokiMessageDatabase = DatabaseFactory.getLokiMessageDatabase(context); + long originalThreadId = threadDatabase.getThreadIdFor(originalRecipient); + lokiMessageDatabase.setOriginalThreadID(result.getMessageId(), originalThreadId); + } } } @@ -958,17 +959,17 @@ public class PushDecryptJob extends BaseJob implements InjectableType { // Loki - Cache the user hex encoded public key (for mentions) MentionManagerUtilities.INSTANCE.populateUserPublicKeyCacheIfNeeded(result.getThreadId(), context); - MentionsManager.shared.cache(textMessage.getSender().serialize(), result.getThreadId()); + MentionsManager.shared.cache(content.getSender(), result.getThreadId()); - // Loki - Store message server ID - if (insertResult.isPresent() && messageServerIDOrNull.isPresent()) { - long messageID = insertResult.get().getMessageId(); + // Loki - Store message open group server ID if needed + if (messageServerIDOrNull.isPresent()) { + long messageID = result.getMessageId(); long messageServerID = messageServerIDOrNull.get(); LokiMessageDatabase lokiMessageDatabase = DatabaseFactory.getLokiMessageDatabase(context); lokiMessageDatabase.setServerID(messageID, messageServerID); } - // Loki - Update mapping of message to original thread ID + // Loki - Update mapping of message ID to original thread ID if (result.getMessageId() > -1) { ThreadDatabase threadDatabase = DatabaseFactory.getThreadDatabase(context); LokiMessageDatabase lokiMessageDatabase = DatabaseFactory.getLokiMessageDatabase(context); @@ -1127,28 +1128,6 @@ public class PushDecryptJob extends BaseJob implements InjectableType { // } } - private void handleProfileKey(@NonNull SignalServiceContent content, - @NonNull SignalServiceDataMessage message) - { - if (!message.getProfileKey().isPresent()) { return; } - - /* - If we get a profile key then we don't need to map it to the primary device. - For now a profile key is mapped one-to-one to avoid secondary devices setting the incorrect avatar for a primary device. - */ - RecipientDatabase database = DatabaseFactory.getRecipientDatabase(context); - Recipient recipient = Recipient.from(context, Address.fromSerialized(content.getSender()), false); - - if (recipient.getProfileKey() == null || !MessageDigest.isEqual(recipient.getProfileKey(), message.getProfileKey().get())) { - database.setProfileKey(recipient, message.getProfileKey().get()); - database.setUnidentifiedAccessMode(recipient, RecipientDatabase.UnidentifiedAccessMode.UNKNOWN); - String url = content.senderProfilePictureURL.or(""); - ApplicationContext.getInstance(context).getJobManager().add(new RetrieveProfileAvatarJob(recipient, url)); - - SessionMetaProtocol.handleProfileKeyUpdateIfNeeded(context, content); - } - } - private void handleNeedsDeliveryReceipt(@NonNull SignalServiceContent content, @NonNull SignalServiceDataMessage message) { diff --git a/src/org/thoughtcrime/securesms/jobs/PushReceivedJob.java b/src/org/thoughtcrime/securesms/jobs/PushReceivedJob.java index 7b96e5593c..63fc0f65d5 100644 --- a/src/org/thoughtcrime/securesms/jobs/PushReceivedJob.java +++ b/src/org/thoughtcrime/securesms/jobs/PushReceivedJob.java @@ -36,7 +36,7 @@ public abstract class PushReceivedJob extends BaseJob { if (envelope.isReceipt()) { handleReceipt(envelope); - } else if (envelope.isPreKeySignalMessage() || envelope.isSignalMessage() || envelope.isUnidentifiedSender()) { + } else if (envelope.isPreKeySignalMessage() || envelope.isSignalMessage() || envelope.isUnidentifiedSender() || envelope.isFallbackMessage()) { handleMessage(envelope, isPushNotification); } else { Log.w(TAG, "Received envelope of unknown type: " + envelope.getType()); diff --git a/src/org/thoughtcrime/securesms/loki/protocol/MultiDeviceProtocol.kt b/src/org/thoughtcrime/securesms/loki/protocol/MultiDeviceProtocol.kt index e1b1ada7a2..e2b6c0f5f5 100644 --- a/src/org/thoughtcrime/securesms/loki/protocol/MultiDeviceProtocol.kt +++ b/src/org/thoughtcrime/securesms/loki/protocol/MultiDeviceProtocol.kt @@ -162,9 +162,6 @@ object MultiDeviceProtocol { } val isValid = isValidDeviceLinkMessage(context, deviceLink) if (!isValid) { return } - // The line below isn't actually necessary because this is called after PushDecryptJob - // calls handlePreKeyBundleMessageIfNeeded, but it also doesn't hurt. - SessionManagementProtocol.handlePreKeyBundleMessageIfNeeded(context, content) linkingSession.processLinkingAuthorization(deviceLink) val userPublicKey = TextSecurePreferences.getLocalNumber(context) DatabaseFactory.getLokiAPIDatabase(context).clearDeviceLinks(userPublicKey) @@ -172,7 +169,6 @@ object MultiDeviceProtocol { TextSecurePreferences.setMasterHexEncodedPublicKey(context, deviceLink.masterPublicKey) TextSecurePreferences.setMultiDevice(context, true) FileServerAPI.shared.addDeviceLink(deviceLink) - org.thoughtcrime.securesms.loki.protocol.SessionMetaProtocol.handleProfileUpdateIfNeeded(context, content) org.thoughtcrime.securesms.loki.protocol.SessionMetaProtocol.duplicate_handleProfileKey(context, content) } diff --git a/src/org/thoughtcrime/securesms/loki/protocol/SessionMetaProtocol.kt b/src/org/thoughtcrime/securesms/loki/protocol/SessionMetaProtocol.kt index 538312f801..8d6184c073 100644 --- a/src/org/thoughtcrime/securesms/loki/protocol/SessionMetaProtocol.kt +++ b/src/org/thoughtcrime/securesms/loki/protocol/SessionMetaProtocol.kt @@ -47,9 +47,8 @@ object SessionMetaProtocol { } } - // FIXME: Basically a duplicate of PushDecryptJob's handleProfileKey @JvmStatic - fun duplicate_handleProfileKey(context: Context, content: SignalServiceContent) { + fun handleProfileKeyUpdate(context: Context, content: SignalServiceContent) { val message = content.dataMessage.get() if (!message.profileKey.isPresent) { return } val database = DatabaseFactory.getRecipientDatabase(context) @@ -59,17 +58,13 @@ object SessionMetaProtocol { database.setUnidentifiedAccessMode(recipient, RecipientDatabase.UnidentifiedAccessMode.UNKNOWN) val url = content.senderProfilePictureURL.or("") ApplicationContext.getInstance(context).jobManager.add(RetrieveProfileAvatarJob(recipient, url)) - handleProfileKeyUpdateIfNeeded(context, content) + val userMasterPublicKey = TextSecurePreferences.getMasterHexEncodedPublicKey(context) + if (userMasterPublicKey == content.sender) { + ApplicationContext.getInstance(context).updateOpenGroupProfilePicturesIfNeeded() + } } } - @JvmStatic - fun handleProfileKeyUpdateIfNeeded(context: Context, content: SignalServiceContent) { - val userMasterPublicKey = TextSecurePreferences.getMasterHexEncodedPublicKey(context) - if (userMasterPublicKey != content.sender) { return } - ApplicationContext.getInstance(context).updateOpenGroupProfilePicturesIfNeeded() - } - /** * Should be invoked for the recipient's master device. */ diff --git a/src/org/thoughtcrime/securesms/notifications/OptimizedMessageNotifier.java b/src/org/thoughtcrime/securesms/notifications/OptimizedMessageNotifier.java index a74c0415dc..ee2601e3ff 100644 --- a/src/org/thoughtcrime/securesms/notifications/OptimizedMessageNotifier.java +++ b/src/org/thoughtcrime/securesms/notifications/OptimizedMessageNotifier.java @@ -40,7 +40,7 @@ public class OptimizedMessageNotifier implements MessageNotifier { @Override public void updateNotification(@NonNull Context context) { - Poller lokiPoller = ApplicationContext.getInstance(context).lokiPoller; + Poller lokiPoller = ApplicationContext.getInstance(context).poller; PublicChatManager publicChatManager = ApplicationContext.getInstance(context).publicChatManager; boolean isCaughtUp = true; if (lokiPoller != null) { @@ -60,7 +60,7 @@ public class OptimizedMessageNotifier implements MessageNotifier { @Override public void updateNotification(@NonNull Context context, long threadId) { - Poller lokiPoller = ApplicationContext.getInstance(context).lokiPoller; + Poller lokiPoller = ApplicationContext.getInstance(context).poller; PublicChatManager publicChatManager = ApplicationContext.getInstance(context).publicChatManager; boolean isCaughtUp = true; if (lokiPoller != null) { @@ -80,7 +80,7 @@ public class OptimizedMessageNotifier implements MessageNotifier { @Override public void updateNotification(@NonNull Context context, long threadId, boolean signal) { - Poller lokiPoller = ApplicationContext.getInstance(context).lokiPoller; + Poller lokiPoller = ApplicationContext.getInstance(context).poller; PublicChatManager publicChatManager = ApplicationContext.getInstance(context).publicChatManager; boolean isCaughtUp = true; if (lokiPoller != null) { @@ -100,7 +100,7 @@ public class OptimizedMessageNotifier implements MessageNotifier { @Override public void updateNotification(@android.support.annotation.NonNull Context context, boolean signal, int reminderCount) { - Poller lokiPoller = ApplicationContext.getInstance(context).lokiPoller; + Poller lokiPoller = ApplicationContext.getInstance(context).poller; PublicChatManager publicChatManager = ApplicationContext.getInstance(context).publicChatManager; boolean isCaughtUp = true; if (lokiPoller != null) {