This commit is contained in:
nielsandriesse 2020-07-16 08:55:29 +10:00
parent 06f547dc88
commit dbdb4ec855
6 changed files with 49 additions and 79 deletions

View File

@ -152,7 +152,7 @@ public class ApplicationContext extends MultiDexApplication implements Dependenc
// Loki // Loki
public MessageNotifier messageNotifier = null; public MessageNotifier messageNotifier = null;
public Poller lokiPoller = null; public Poller poller = null;
public PublicChatManager publicChatManager = null; public PublicChatManager publicChatManager = null;
private PublicChatAPI publicChatAPI = null; private PublicChatAPI publicChatAPI = null;
public Broadcaster broadcaster = null; public Broadcaster broadcaster = null;
@ -226,7 +226,7 @@ public class ApplicationContext extends MultiDexApplication implements Dependenc
executePendingContactSync(); executePendingContactSync();
KeyCachingService.onAppForegrounded(this); KeyCachingService.onAppForegrounded(this);
// Loki // Loki
if (lokiPoller != null) { lokiPoller.setCaughtUp(false); } if (poller != null) { poller.setCaughtUp(false); }
startPollingIfNeeded(); startPollingIfNeeded();
publicChatManager.markAllAsNotCaughtUp(); publicChatManager.markAllAsNotCaughtUp();
publicChatManager.startPollersIfNeeded(); publicChatManager.startPollersIfNeeded();
@ -239,7 +239,7 @@ public class ApplicationContext extends MultiDexApplication implements Dependenc
KeyCachingService.onAppBackgrounded(this); KeyCachingService.onAppBackgrounded(this);
messageNotifier.setVisibleThread(-1); messageNotifier.setVisibleThread(-1);
// Loki // Loki
if (lokiPoller != null) { lokiPoller.stopIfNeeded(); } if (poller != null) { poller.stopIfNeeded(); }
if (publicChatManager != null) { publicChatManager.stopPollers(); } if (publicChatManager != null) { publicChatManager.stopPollers(); }
} }
@ -491,16 +491,16 @@ public class ApplicationContext extends MultiDexApplication implements Dependenc
private void setUpPollingIfNeeded() { private void setUpPollingIfNeeded() {
String userPublicKey = TextSecurePreferences.getLocalNumber(this); String userPublicKey = TextSecurePreferences.getLocalNumber(this);
if (userPublicKey == null) return; if (userPublicKey == null) return;
if (lokiPoller != null) { if (poller != null) {
SnodeAPI.shared.setUserPublicKey(userPublicKey); SnodeAPI.shared.setUserPublicKey(userPublicKey);
lokiPoller.setUserPublicKey(userPublicKey); poller.setUserPublicKey(userPublicKey);
return; return;
} }
LokiAPIDatabase apiDB = DatabaseFactory.getLokiAPIDatabase(this); LokiAPIDatabase apiDB = DatabaseFactory.getLokiAPIDatabase(this);
Context context = this; Context context = this;
SwarmAPI.Companion.configureIfNeeded(apiDB); SwarmAPI.Companion.configureIfNeeded(apiDB);
SnodeAPI.Companion.configureIfNeeded(userPublicKey, apiDB, broadcaster); SnodeAPI.Companion.configureIfNeeded(userPublicKey, apiDB, broadcaster);
lokiPoller = new Poller(userPublicKey, apiDB, protos -> { poller = new Poller(userPublicKey, apiDB, protos -> {
for (SignalServiceProtos.Envelope proto : protos) { for (SignalServiceProtos.Envelope proto : protos) {
new PushContentReceiveJob(context).processEnvelope(new SignalServiceEnvelope(proto), false); new PushContentReceiveJob(context).processEnvelope(new SignalServiceEnvelope(proto), false);
} }
@ -510,12 +510,12 @@ public class ApplicationContext extends MultiDexApplication implements Dependenc
public void startPollingIfNeeded() { public void startPollingIfNeeded() {
setUpPollingIfNeeded(); setUpPollingIfNeeded();
if (lokiPoller != null) { lokiPoller.startIfNeeded(); } if (poller != null) { poller.startIfNeeded(); }
} }
public void stopPolling() { public void stopPolling() {
if (lokiPoller == null) { return; } if (poller == null) { return; }
lokiPoller.stopIfNeeded(); poller.stopIfNeeded();
} }
private void resubmitProfilePictureIfNeeded() { private void resubmitProfilePictureIfNeeded() {

View File

@ -48,7 +48,6 @@ import org.thoughtcrime.securesms.database.MessagingDatabase.SyncMessageId;
import org.thoughtcrime.securesms.database.MmsDatabase; import org.thoughtcrime.securesms.database.MmsDatabase;
import org.thoughtcrime.securesms.database.NoSuchMessageException; import org.thoughtcrime.securesms.database.NoSuchMessageException;
import org.thoughtcrime.securesms.database.PushDatabase; import org.thoughtcrime.securesms.database.PushDatabase;
import org.thoughtcrime.securesms.database.RecipientDatabase;
import org.thoughtcrime.securesms.database.SmsDatabase; import org.thoughtcrime.securesms.database.SmsDatabase;
import org.thoughtcrime.securesms.database.StickerDatabase; import org.thoughtcrime.securesms.database.StickerDatabase;
import org.thoughtcrime.securesms.database.ThreadDatabase; 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.database.LokiMessageDatabase;
import org.thoughtcrime.securesms.loki.protocol.ClosedGroupsProtocol; import org.thoughtcrime.securesms.loki.protocol.ClosedGroupsProtocol;
import org.thoughtcrime.securesms.loki.protocol.MultiDeviceProtocol; 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.SessionManagementProtocol;
import org.thoughtcrime.securesms.loki.protocol.SessionMetaProtocol; import org.thoughtcrime.securesms.loki.protocol.SessionMetaProtocol;
import org.thoughtcrime.securesms.loki.protocol.SessionResetImplementation; 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.protocol.mentions.MentionsManager;
import org.whispersystems.signalservice.loki.utilities.PublicKeyValidation; import org.whispersystems.signalservice.loki.utilities.PublicKeyValidation;
import java.security.MessageDigest;
import java.security.SecureRandom; import java.security.SecureRandom;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Collections; import java.util.Collections;
@ -298,7 +295,7 @@ public class PushDecryptJob extends BaseJob implements InjectableType {
} }
if (message.getProfileKey().isPresent() && message.getProfileKey().get().length == 32) { if (message.getProfileKey().isPresent() && message.getProfileKey().get().length == 32) {
handleProfileKey(content, message); SessionMetaProtocol.handleProfileKeyUpdate(context, content);
} }
if (content.isNeedsReceipt()) { if (content.isNeedsReceipt()) {
@ -335,13 +332,9 @@ public class PushDecryptJob extends BaseJob implements InjectableType {
else if (message.isDeliveryReceipt()) handleDeliveryReceipt(content, message); else if (message.isDeliveryReceipt()) handleDeliveryReceipt(content, message);
} else if (content.getTypingMessage().isPresent()) { } else if (content.getTypingMessage().isPresent()) {
handleTypingMessage(content, content.getTypingMessage().get()); handleTypingMessage(content, content.getTypingMessage().get());
} else if (content.getNullMessage().isPresent()) {
if (content.preKeyBundleMessage.isPresent()) {
ApplicationContext.getInstance(context).getJobManager().add(new PushNullMessageSendJob(content.getSender()));
} else { } else {
Log.w(TAG, "Got unrecognized message..."); Log.w(TAG, "Got unrecognized message...");
} }
}
resetRecipientToPush(Recipient.from(context, Address.fromSerialized(content.getSender()), false)); 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); DatabaseFactory.getRecipientDatabase(context).setProfileSharing(recipient, true);
} }
handleProfileKey(content, message.getMessage()); SessionMetaProtocol.handleProfileKeyUpdate(context, content);
} }
SessionMetaProtocol.handleProfileUpdateIfNeeded(context, content); SessionMetaProtocol.handleProfileUpdateIfNeeded(context, content);
@ -781,20 +774,28 @@ public class PushDecryptJob extends BaseJob implements InjectableType {
messageNotifier.updateNotification(context, insertResult.get().getThreadId()); messageNotifier.updateNotification(context, insertResult.get().getThreadId());
} }
if (insertResult.isPresent()) {
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 // Loki - Store message open group server ID if needed
if (insertResult.isPresent() && messageServerIDOrNull.isPresent()) { if (messageServerIDOrNull.isPresent()) {
long messageID = insertResult.get().getMessageId(); long messageID = result.getMessageId();
long messageServerID = messageServerIDOrNull.get(); long messageServerID = messageServerIDOrNull.get();
LokiMessageDatabase lokiMessageDatabase = DatabaseFactory.getLokiMessageDatabase(context); LokiMessageDatabase lokiMessageDatabase = DatabaseFactory.getLokiMessageDatabase(context);
lokiMessageDatabase.setServerID(messageID, messageServerID); lokiMessageDatabase.setServerID(messageID, messageServerID);
} }
// Loki - Update mapping of message ID to original thread ID // Loki - Update mapping of message ID to original thread ID
if (insertResult.isPresent()) { if (result.getMessageId() > -1) {
ThreadDatabase threadDatabase = DatabaseFactory.getThreadDatabase(context); ThreadDatabase threadDatabase = DatabaseFactory.getThreadDatabase(context);
LokiMessageDatabase lokiMessageDatabase = DatabaseFactory.getLokiMessageDatabase(context); LokiMessageDatabase lokiMessageDatabase = DatabaseFactory.getLokiMessageDatabase(context);
long originalThreadId = threadDatabase.getThreadIdFor(originalRecipient); long originalThreadId = threadDatabase.getThreadIdFor(originalRecipient);
lokiMessageDatabase.setOriginalThreadID(insertResult.get().getMessageId(), originalThreadId); 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) // Loki - Cache the user hex encoded public key (for mentions)
MentionManagerUtilities.INSTANCE.populateUserPublicKeyCacheIfNeeded(result.getThreadId(), context); 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 // Loki - Store message open group server ID if needed
if (insertResult.isPresent() && messageServerIDOrNull.isPresent()) { if (messageServerIDOrNull.isPresent()) {
long messageID = insertResult.get().getMessageId(); long messageID = result.getMessageId();
long messageServerID = messageServerIDOrNull.get(); long messageServerID = messageServerIDOrNull.get();
LokiMessageDatabase lokiMessageDatabase = DatabaseFactory.getLokiMessageDatabase(context); LokiMessageDatabase lokiMessageDatabase = DatabaseFactory.getLokiMessageDatabase(context);
lokiMessageDatabase.setServerID(messageID, messageServerID); 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) { if (result.getMessageId() > -1) {
ThreadDatabase threadDatabase = DatabaseFactory.getThreadDatabase(context); ThreadDatabase threadDatabase = DatabaseFactory.getThreadDatabase(context);
LokiMessageDatabase lokiMessageDatabase = DatabaseFactory.getLokiMessageDatabase(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, private void handleNeedsDeliveryReceipt(@NonNull SignalServiceContent content,
@NonNull SignalServiceDataMessage message) @NonNull SignalServiceDataMessage message)
{ {

View File

@ -36,7 +36,7 @@ public abstract class PushReceivedJob extends BaseJob {
if (envelope.isReceipt()) { if (envelope.isReceipt()) {
handleReceipt(envelope); handleReceipt(envelope);
} else if (envelope.isPreKeySignalMessage() || envelope.isSignalMessage() || envelope.isUnidentifiedSender()) { } else if (envelope.isPreKeySignalMessage() || envelope.isSignalMessage() || envelope.isUnidentifiedSender() || envelope.isFallbackMessage()) {
handleMessage(envelope, isPushNotification); handleMessage(envelope, isPushNotification);
} else { } else {
Log.w(TAG, "Received envelope of unknown type: " + envelope.getType()); Log.w(TAG, "Received envelope of unknown type: " + envelope.getType());

View File

@ -162,9 +162,6 @@ object MultiDeviceProtocol {
} }
val isValid = isValidDeviceLinkMessage(context, deviceLink) val isValid = isValidDeviceLinkMessage(context, deviceLink)
if (!isValid) { return } 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) linkingSession.processLinkingAuthorization(deviceLink)
val userPublicKey = TextSecurePreferences.getLocalNumber(context) val userPublicKey = TextSecurePreferences.getLocalNumber(context)
DatabaseFactory.getLokiAPIDatabase(context).clearDeviceLinks(userPublicKey) DatabaseFactory.getLokiAPIDatabase(context).clearDeviceLinks(userPublicKey)
@ -172,7 +169,6 @@ object MultiDeviceProtocol {
TextSecurePreferences.setMasterHexEncodedPublicKey(context, deviceLink.masterPublicKey) TextSecurePreferences.setMasterHexEncodedPublicKey(context, deviceLink.masterPublicKey)
TextSecurePreferences.setMultiDevice(context, true) TextSecurePreferences.setMultiDevice(context, true)
FileServerAPI.shared.addDeviceLink(deviceLink) FileServerAPI.shared.addDeviceLink(deviceLink)
org.thoughtcrime.securesms.loki.protocol.SessionMetaProtocol.handleProfileUpdateIfNeeded(context, content)
org.thoughtcrime.securesms.loki.protocol.SessionMetaProtocol.duplicate_handleProfileKey(context, content) org.thoughtcrime.securesms.loki.protocol.SessionMetaProtocol.duplicate_handleProfileKey(context, content)
} }

View File

@ -47,9 +47,8 @@ object SessionMetaProtocol {
} }
} }
// FIXME: Basically a duplicate of PushDecryptJob's handleProfileKey
@JvmStatic @JvmStatic
fun duplicate_handleProfileKey(context: Context, content: SignalServiceContent) { fun handleProfileKeyUpdate(context: Context, content: SignalServiceContent) {
val message = content.dataMessage.get() val message = content.dataMessage.get()
if (!message.profileKey.isPresent) { return } if (!message.profileKey.isPresent) { return }
val database = DatabaseFactory.getRecipientDatabase(context) val database = DatabaseFactory.getRecipientDatabase(context)
@ -59,16 +58,12 @@ object SessionMetaProtocol {
database.setUnidentifiedAccessMode(recipient, RecipientDatabase.UnidentifiedAccessMode.UNKNOWN) database.setUnidentifiedAccessMode(recipient, RecipientDatabase.UnidentifiedAccessMode.UNKNOWN)
val url = content.senderProfilePictureURL.or("") val url = content.senderProfilePictureURL.or("")
ApplicationContext.getInstance(context).jobManager.add(RetrieveProfileAvatarJob(recipient, url)) ApplicationContext.getInstance(context).jobManager.add(RetrieveProfileAvatarJob(recipient, url))
handleProfileKeyUpdateIfNeeded(context, content)
}
}
@JvmStatic
fun handleProfileKeyUpdateIfNeeded(context: Context, content: SignalServiceContent) {
val userMasterPublicKey = TextSecurePreferences.getMasterHexEncodedPublicKey(context) val userMasterPublicKey = TextSecurePreferences.getMasterHexEncodedPublicKey(context)
if (userMasterPublicKey != content.sender) { return } if (userMasterPublicKey == content.sender) {
ApplicationContext.getInstance(context).updateOpenGroupProfilePicturesIfNeeded() ApplicationContext.getInstance(context).updateOpenGroupProfilePicturesIfNeeded()
} }
}
}
/** /**
* Should be invoked for the recipient's master device. * Should be invoked for the recipient's master device.

View File

@ -40,7 +40,7 @@ public class OptimizedMessageNotifier implements MessageNotifier {
@Override @Override
public void updateNotification(@NonNull Context context) { public void updateNotification(@NonNull Context context) {
Poller lokiPoller = ApplicationContext.getInstance(context).lokiPoller; Poller lokiPoller = ApplicationContext.getInstance(context).poller;
PublicChatManager publicChatManager = ApplicationContext.getInstance(context).publicChatManager; PublicChatManager publicChatManager = ApplicationContext.getInstance(context).publicChatManager;
boolean isCaughtUp = true; boolean isCaughtUp = true;
if (lokiPoller != null) { if (lokiPoller != null) {
@ -60,7 +60,7 @@ public class OptimizedMessageNotifier implements MessageNotifier {
@Override @Override
public void updateNotification(@NonNull Context context, long threadId) { 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; PublicChatManager publicChatManager = ApplicationContext.getInstance(context).publicChatManager;
boolean isCaughtUp = true; boolean isCaughtUp = true;
if (lokiPoller != null) { if (lokiPoller != null) {
@ -80,7 +80,7 @@ public class OptimizedMessageNotifier implements MessageNotifier {
@Override @Override
public void updateNotification(@NonNull Context context, long threadId, boolean signal) { 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; PublicChatManager publicChatManager = ApplicationContext.getInstance(context).publicChatManager;
boolean isCaughtUp = true; boolean isCaughtUp = true;
if (lokiPoller != null) { if (lokiPoller != null) {
@ -100,7 +100,7 @@ public class OptimizedMessageNotifier implements MessageNotifier {
@Override @Override
public void updateNotification(@android.support.annotation.NonNull Context context, boolean signal, int reminderCount) { 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; PublicChatManager publicChatManager = ApplicationContext.getInstance(context).publicChatManager;
boolean isCaughtUp = true; boolean isCaughtUp = true;
if (lokiPoller != null) { if (lokiPoller != null) {