mirror of
https://github.com/oxen-io/session-android.git
synced 2025-08-11 17:27:42 +00:00
WIP: clean up signal protocols
This commit is contained in:
@@ -76,7 +76,6 @@ import org.thoughtcrime.securesms.loki.database.LokiAPIDatabase;
|
||||
import org.thoughtcrime.securesms.loki.database.LokiThreadDatabase;
|
||||
import org.thoughtcrime.securesms.loki.database.LokiUserDatabase;
|
||||
import org.thoughtcrime.securesms.loki.protocol.MultiDeviceProtocol;
|
||||
import org.thoughtcrime.securesms.loki.protocol.SessionResetImplementation;
|
||||
import org.thoughtcrime.securesms.loki.utilities.Broadcaster;
|
||||
import org.thoughtcrime.securesms.loki.utilities.UiModeUtilities;
|
||||
import org.thoughtcrime.securesms.notifications.DefaultMessageNotifier;
|
||||
@@ -84,7 +83,6 @@ import org.thoughtcrime.securesms.notifications.NotificationChannels;
|
||||
import org.thoughtcrime.securesms.notifications.OptimizedMessageNotifier;
|
||||
import org.thoughtcrime.securesms.providers.BlobProvider;
|
||||
import org.thoughtcrime.securesms.push.SignalServiceNetworkAccess;
|
||||
import org.session.libsession.messaging.threads.recipients.Recipient;
|
||||
import org.thoughtcrime.securesms.service.ExpiringMessageManager;
|
||||
import org.thoughtcrime.securesms.service.IncomingMessageObserver;
|
||||
import org.thoughtcrime.securesms.service.KeyCachingService;
|
||||
@@ -107,8 +105,7 @@ import org.session.libsignal.service.loki.api.opengroups.PublicChatAPI;
|
||||
import org.session.libsignal.service.loki.api.shelved.p2p.LokiP2PAPI;
|
||||
import org.session.libsignal.service.loki.api.shelved.p2p.LokiP2PAPIDelegate;
|
||||
import org.session.libsignal.service.loki.database.LokiAPIDatabaseProtocol;
|
||||
import org.session.libsignal.service.loki.protocol.mentions.MentionsManager;
|
||||
import org.session.libsignal.service.loki.protocol.meta.SessionMetaProtocol;
|
||||
import org.session.libsignal.service.loki.utilities.mentions.MentionsManager;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileInputStream;
|
||||
@@ -136,7 +133,6 @@ import static nl.komponents.kovenant.android.KovenantAndroid.stopKovenant;
|
||||
public class ApplicationContext extends MultiDexApplication implements DependencyInjector, DefaultLifecycleObserver, LokiP2PAPIDelegate {
|
||||
|
||||
private static final String TAG = ApplicationContext.class.getSimpleName();
|
||||
private final static int OK_HTTP_CACHE_SIZE = 10 * 1024 * 1024; // 10 MB
|
||||
|
||||
private ExpiringMessageManager expiringMessageManager;
|
||||
private TypingStatusRepository typingStatusRepository;
|
||||
@@ -144,7 +140,6 @@ public class ApplicationContext extends MultiDexApplication implements Dependenc
|
||||
private JobManager jobManager;
|
||||
private ReadReceiptManager readReceiptManager;
|
||||
private ProfileManager profileManager;
|
||||
private IncomingMessageObserver incomingMessageObserver;
|
||||
private ObjectGraph objectGraph;
|
||||
private PersistentLogger persistentLogger;
|
||||
|
||||
@@ -182,7 +177,6 @@ public class ApplicationContext extends MultiDexApplication implements Dependenc
|
||||
LokiThreadDatabase threadDB = DatabaseFactory.getLokiThreadDatabase(this);
|
||||
LokiUserDatabase userDB = DatabaseFactory.getLokiUserDatabase(this);
|
||||
String userPublicKey = TextSecurePreferences.getLocalNumber(this);
|
||||
SessionResetImplementation sessionResetImpl = new SessionResetImplementation(this);
|
||||
MessagingConfiguration.Companion.configure(this,
|
||||
DatabaseFactory.getStorage(this),
|
||||
DatabaseFactory.getAttachmentProvider(this),
|
||||
@@ -191,7 +185,6 @@ public class ApplicationContext extends MultiDexApplication implements Dependenc
|
||||
SwarmAPI.Companion.configureIfNeeded(apiDB);
|
||||
SnodeAPI.Companion.configureIfNeeded(userPublicKey, apiDB, broadcaster);
|
||||
MentionsManager.Companion.configureIfNeeded(userPublicKey, threadDB, userDB);
|
||||
SessionMetaProtocol.Companion.configureIfNeeded(apiDB, userPublicKey);
|
||||
}
|
||||
setUpP2PAPIIfNeeded();
|
||||
PushNotificationAPI.Companion.configureIfNeeded(BuildConfig.DEBUG);
|
||||
@@ -206,7 +199,6 @@ public class ApplicationContext extends MultiDexApplication implements Dependenc
|
||||
UiModeUtilities.setupUiModeToUserSelected(this);
|
||||
// ========
|
||||
initializeJobManager();
|
||||
initializeMessageRetrieval();
|
||||
initializeExpiringMessageManager();
|
||||
initializeTypingStatusRepository();
|
||||
initializeTypingStatusSender();
|
||||
@@ -347,10 +339,6 @@ public class ApplicationContext extends MultiDexApplication implements Dependenc
|
||||
.build());
|
||||
}
|
||||
|
||||
public void initializeMessageRetrieval() {
|
||||
this.incomingMessageObserver = new IncomingMessageObserver(this);
|
||||
}
|
||||
|
||||
private void initializeDependencyInjection() {
|
||||
communicationModule = new SignalCommunicationModule(this, new SignalServiceNetworkAccess(this));
|
||||
this.objectGraph = ObjectGraph.create(communicationModule);
|
||||
|
@@ -90,9 +90,8 @@ import org.session.libsession.utilities.MediaTypes;
|
||||
import org.session.libsignal.libsignal.InvalidMessageException;
|
||||
import org.session.libsignal.libsignal.util.guava.Optional;
|
||||
import org.session.libsignal.service.loki.api.opengroups.PublicChat;
|
||||
import org.session.libsignal.service.loki.protocol.mentions.Mention;
|
||||
import org.session.libsignal.service.loki.protocol.mentions.MentionsManager;
|
||||
import org.session.libsignal.service.loki.protocol.meta.SessionMetaProtocol;
|
||||
import org.session.libsignal.service.loki.utilities.mentions.Mention;
|
||||
import org.session.libsignal.service.loki.utilities.mentions.MentionsManager;
|
||||
import org.session.libsignal.service.loki.utilities.HexEncodingKt;
|
||||
import org.session.libsignal.service.loki.utilities.PublicKeyValidation;
|
||||
import org.thoughtcrime.securesms.ApplicationContext;
|
||||
@@ -144,7 +143,6 @@ import org.thoughtcrime.securesms.loki.database.LokiThreadDatabase;
|
||||
import org.thoughtcrime.securesms.loki.database.LokiThreadDatabaseDelegate;
|
||||
import org.thoughtcrime.securesms.loki.database.LokiUserDatabase;
|
||||
import org.thoughtcrime.securesms.loki.protocol.ClosedGroupsProtocolV2;
|
||||
import org.thoughtcrime.securesms.loki.protocol.SessionManagementProtocol;
|
||||
import org.thoughtcrime.securesms.loki.utilities.GeneralUtilitiesKt;
|
||||
import org.thoughtcrime.securesms.loki.utilities.MentionManagerUtilities;
|
||||
import org.thoughtcrime.securesms.loki.utilities.OpenGroupUtilities;
|
||||
@@ -404,7 +402,6 @@ public class ConversationActivity extends PassphraseRequiredActionBarActivity
|
||||
});
|
||||
|
||||
sessionRestoreBannerView.setOnRestore(() -> {
|
||||
SessionManagementProtocol.startSessionReset(this, recipient.getAddress().serialize());
|
||||
updateSessionRestoreBanner();
|
||||
return Unit.INSTANCE;
|
||||
});
|
||||
@@ -2003,7 +2000,7 @@ public class ConversationActivity extends PassphraseRequiredActionBarActivity
|
||||
Log.w(TAG, ex);
|
||||
}
|
||||
|
||||
if (messageStatus == null && !isGroupConversation() && !SessionMetaProtocol.shared.isNoteToSelf(recipient.getAddress().serialize())) {
|
||||
if (messageStatus == null && !isGroupConversation() && !(TextSecurePreferences.getLocalNumber(this).equals(recipient.getAddress().serialize()))) {
|
||||
messageStatus = "calculatingPoW";
|
||||
updateSubtitleTextView();
|
||||
updateMessageStatusProgressBar();
|
||||
@@ -2680,7 +2677,7 @@ public class ConversationActivity extends PassphraseRequiredActionBarActivity
|
||||
}
|
||||
|
||||
private void handleMessageStatusChanged(String newMessageStatus, long timestamp) {
|
||||
if (timestamp == 0 || SessionMetaProtocol.shared.isNoteToSelf(recipient.getAddress().serialize()) ) { return; }
|
||||
if (timestamp == 0 || (TextSecurePreferences.getLocalNumber(this).equals(recipient.getAddress().serialize())) ) { return; }
|
||||
updateForNewMessageStatusIfNeeded(newMessageStatus, timestamp);
|
||||
if (newMessageStatus.equals("messageFailed") || newMessageStatus.equals("messageSent")) {
|
||||
new Handler().postDelayed(() -> clearMessageStatusIfNeeded(timestamp), 1000);
|
||||
|
@@ -49,11 +49,11 @@ public class PushDatabase extends Database {
|
||||
values.put(TYPE, envelope.getType());
|
||||
values.put(SOURCE, envelope.getSource());
|
||||
values.put(DEVICE_ID, envelope.getSourceDevice());
|
||||
values.put(LEGACY_MSG, envelope.hasLegacyMessage() ? Base64.encodeBytes(envelope.getLegacyMessage()) : "");
|
||||
values.put(LEGACY_MSG, "");
|
||||
values.put(CONTENT, envelope.hasContent() ? Base64.encodeBytes(envelope.getContent()) : "");
|
||||
values.put(TIMESTAMP, envelope.getTimestamp());
|
||||
values.put(SERVER_TIMESTAMP, envelope.getServerTimestamp());
|
||||
values.put(SERVER_GUID, envelope.getUuid());
|
||||
values.put(SERVER_GUID, "");
|
||||
|
||||
return databaseHelper.getWritableDatabase().insert(TABLE_NAME, null, values);
|
||||
}
|
||||
@@ -68,17 +68,14 @@ public class PushDatabase extends Database {
|
||||
null, null, null);
|
||||
|
||||
if (cursor != null && cursor.moveToNext()) {
|
||||
String legacyMessage = cursor.getString(cursor.getColumnIndexOrThrow(LEGACY_MSG));
|
||||
String content = cursor.getString(cursor.getColumnIndexOrThrow(CONTENT));
|
||||
|
||||
return new SignalServiceEnvelope(cursor.getInt(cursor.getColumnIndexOrThrow(TYPE)),
|
||||
cursor.getString(cursor.getColumnIndexOrThrow(SOURCE)),
|
||||
cursor.getInt(cursor.getColumnIndexOrThrow(DEVICE_ID)),
|
||||
cursor.getLong(cursor.getColumnIndexOrThrow(TIMESTAMP)),
|
||||
Util.isEmpty(legacyMessage) ? null : Base64.decode(legacyMessage),
|
||||
Util.isEmpty(content) ? null : Base64.decode(content),
|
||||
cursor.getLong(cursor.getColumnIndexOrThrow(SERVER_TIMESTAMP)),
|
||||
cursor.getString(cursor.getColumnIndexOrThrow(SERVER_GUID)));
|
||||
cursor.getLong(cursor.getColumnIndexOrThrow(SERVER_TIMESTAMP)));
|
||||
}
|
||||
} catch (IOException e) {
|
||||
Log.w(TAG, e);
|
||||
@@ -114,7 +111,7 @@ public class PushDatabase extends Database {
|
||||
new String[] {String.valueOf(envelope.getType()),
|
||||
envelope.getSource(),
|
||||
String.valueOf(envelope.getSourceDevice()),
|
||||
envelope.hasLegacyMessage() ? Base64.encodeBytes(envelope.getLegacyMessage()) : "",
|
||||
"",
|
||||
envelope.hasContent() ? Base64.encodeBytes(envelope.getContent()) : "",
|
||||
String.valueOf(envelope.getTimestamp())},
|
||||
null, null, null);
|
||||
@@ -144,16 +141,13 @@ public class PushDatabase extends Database {
|
||||
int type = cursor.getInt(cursor.getColumnIndexOrThrow(TYPE));
|
||||
String source = cursor.getString(cursor.getColumnIndexOrThrow(SOURCE));
|
||||
int deviceId = cursor.getInt(cursor.getColumnIndexOrThrow(DEVICE_ID));
|
||||
String legacyMessage = cursor.getString(cursor.getColumnIndexOrThrow(LEGACY_MSG));
|
||||
String content = cursor.getString(cursor.getColumnIndexOrThrow(CONTENT));
|
||||
long timestamp = cursor.getLong(cursor.getColumnIndexOrThrow(TIMESTAMP));
|
||||
long serverTimestamp = cursor.getLong(cursor.getColumnIndexOrThrow(SERVER_TIMESTAMP));
|
||||
String serverGuid = cursor.getString(cursor.getColumnIndexOrThrow(SERVER_GUID));
|
||||
|
||||
return new SignalServiceEnvelope(type, source, deviceId, timestamp,
|
||||
legacyMessage != null ? Base64.decode(legacyMessage) : null,
|
||||
content != null ? Base64.decode(content) : null,
|
||||
serverTimestamp, serverGuid);
|
||||
serverTimestamp);
|
||||
} catch (IOException e) {
|
||||
throw new AssertionError(e);
|
||||
}
|
||||
|
@@ -250,7 +250,9 @@ public class SQLCipherOpenHelper extends SQLiteOpenHelper {
|
||||
}
|
||||
|
||||
if (oldVersion < lokiV21) {
|
||||
deleteJobRecords(db, "ClosedGroupUpdateMessageSendJob");
|
||||
deleteJobRecords(db,
|
||||
"ClosedGroupUpdateMessageSendJob",
|
||||
"NullMessageSendJob");
|
||||
}
|
||||
|
||||
db.setTransactionSuccessful();
|
||||
|
@@ -32,7 +32,6 @@ import org.thoughtcrime.securesms.jobs.TypingSendJob;
|
||||
import org.thoughtcrime.securesms.linkpreview.LinkPreviewRepository;
|
||||
import org.session.libsignal.utilities.logging.Log;
|
||||
import org.thoughtcrime.securesms.loki.api.SessionProtocolImpl;
|
||||
import org.thoughtcrime.securesms.loki.protocol.SessionResetImplementation;
|
||||
import org.thoughtcrime.securesms.preferences.AppProtectionPreferenceFragment;
|
||||
import org.thoughtcrime.securesms.push.MessageSenderEventListener;
|
||||
import org.thoughtcrime.securesms.push.SignalServiceNetworkAccess;
|
||||
@@ -88,20 +87,15 @@ public class SignalCommunicationModule {
|
||||
@Provides
|
||||
public synchronized SignalServiceMessageSender provideSignalMessageSender() {
|
||||
if (this.messageSender == null) {
|
||||
this.messageSender = new SignalServiceMessageSender(networkAccess.getConfiguration(context),
|
||||
new DynamicCredentialsProvider(context),
|
||||
this.messageSender = new SignalServiceMessageSender(new DynamicCredentialsProvider(context),
|
||||
new SignalProtocolStoreImpl(context),
|
||||
BuildConfig.USER_AGENT,
|
||||
Optional.fromNullable(IncomingMessageObserver.getPipe()),
|
||||
Optional.fromNullable(IncomingMessageObserver.getUnidentifiedPipe()),
|
||||
Optional.of(new MessageSenderEventListener(context)),
|
||||
TextSecurePreferences.getLocalNumber(context),
|
||||
DatabaseFactory.getLokiAPIDatabase(context),
|
||||
DatabaseFactory.getLokiThreadDatabase(context),
|
||||
DatabaseFactory.getLokiMessageDatabase(context),
|
||||
null, // DatabaseFactory.getLokiPreKeyBundleDatabase(context)
|
||||
new SessionProtocolImpl(context),
|
||||
new SessionResetImplementation(context),
|
||||
DatabaseFactory.getLokiUserDatabase(context),
|
||||
DatabaseFactory.getGroupDatabase(context),
|
||||
((ApplicationContext)context.getApplicationContext()).broadcaster);
|
||||
|
@@ -17,7 +17,6 @@ import org.thoughtcrime.securesms.jobmanager.impl.SqlCipherMigrationConstraintOb
|
||||
import org.thoughtcrime.securesms.loki.api.PrepareAttachmentAudioExtrasJob;
|
||||
import org.thoughtcrime.securesms.loki.api.ResetThreadSessionJob;
|
||||
import org.thoughtcrime.securesms.loki.protocol.ClosedGroupUpdateMessageSendJobV2;
|
||||
import org.thoughtcrime.securesms.loki.protocol.NullMessageSendJob;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
@@ -41,7 +40,6 @@ public final class JobManagerFactories {
|
||||
put(MmsDownloadJob.KEY, new MmsDownloadJob.Factory());
|
||||
put(MmsReceiveJob.KEY, new MmsReceiveJob.Factory());
|
||||
put(MmsSendJob.KEY, new MmsSendJob.Factory());
|
||||
put(NullMessageSendJob.KEY, new NullMessageSendJob.Factory());
|
||||
put(PushContentReceiveJob.KEY, new PushContentReceiveJob.Factory());
|
||||
put(PushDecryptJob.KEY, new PushDecryptJob.Factory());
|
||||
put(PushGroupSendJob.KEY, new PushGroupSendJob.Factory());
|
||||
|
@@ -17,19 +17,8 @@ import com.annimon.stream.Stream;
|
||||
import org.session.libsession.messaging.jobs.Data;
|
||||
import org.session.libsession.utilities.MediaTypes;
|
||||
import org.session.libsignal.metadata.InvalidMetadataMessageException;
|
||||
import org.session.libsignal.metadata.InvalidMetadataVersionException;
|
||||
import org.session.libsignal.metadata.ProtocolDuplicateMessageException;
|
||||
import org.session.libsignal.metadata.ProtocolInvalidKeyException;
|
||||
import org.session.libsignal.metadata.ProtocolInvalidKeyIdException;
|
||||
import org.session.libsignal.metadata.ProtocolInvalidMessageException;
|
||||
import org.session.libsignal.metadata.ProtocolInvalidVersionException;
|
||||
import org.session.libsignal.metadata.ProtocolLegacyMessageException;
|
||||
import org.session.libsignal.metadata.ProtocolNoSessionException;
|
||||
import org.session.libsignal.metadata.ProtocolUntrustedIdentityException;
|
||||
import org.session.libsignal.metadata.SelfSendException;
|
||||
import org.session.libsignal.service.api.crypto.SignalServiceCipher;
|
||||
import org.session.libsignal.service.loki.api.crypto.SessionProtocol;
|
||||
import org.session.libsignal.utilities.PromiseUtilities;
|
||||
import org.thoughtcrime.securesms.ApplicationContext;
|
||||
|
||||
import org.session.libsession.messaging.sending_receiving.linkpreview.LinkPreview;
|
||||
@@ -48,13 +37,10 @@ import org.session.libsession.utilities.TextSecurePreferences;
|
||||
|
||||
import org.thoughtcrime.securesms.contactshare.ContactModelMapper;
|
||||
import org.thoughtcrime.securesms.crypto.IdentityKeyUtil;
|
||||
import org.thoughtcrime.securesms.crypto.UnidentifiedAccessUtil;
|
||||
import org.thoughtcrime.securesms.crypto.storage.SignalProtocolStoreImpl;
|
||||
import org.thoughtcrime.securesms.database.AttachmentDatabase;
|
||||
import org.thoughtcrime.securesms.database.DatabaseFactory;
|
||||
import org.thoughtcrime.securesms.database.GroupDatabase;
|
||||
import org.thoughtcrime.securesms.database.GroupReceiptDatabase;
|
||||
import org.thoughtcrime.securesms.database.MessagingDatabase;
|
||||
import org.thoughtcrime.securesms.database.MessagingDatabase.InsertResult;
|
||||
import org.thoughtcrime.securesms.database.MessagingDatabase.SyncMessageId;
|
||||
import org.thoughtcrime.securesms.database.MmsDatabase;
|
||||
@@ -79,26 +65,19 @@ import org.thoughtcrime.securesms.loki.database.LokiMessageDatabase;
|
||||
import org.thoughtcrime.securesms.loki.database.LokiThreadDatabase;
|
||||
import org.thoughtcrime.securesms.loki.protocol.ClosedGroupsProtocolV2;
|
||||
import org.thoughtcrime.securesms.loki.protocol.MultiDeviceProtocol;
|
||||
import org.thoughtcrime.securesms.loki.protocol.SessionManagementProtocol;
|
||||
import org.thoughtcrime.securesms.loki.protocol.SessionMetaProtocol;
|
||||
import org.thoughtcrime.securesms.loki.protocol.SessionResetImplementation;
|
||||
import org.thoughtcrime.securesms.loki.utilities.MentionManagerUtilities;
|
||||
import org.thoughtcrime.securesms.mms.IncomingMediaMessage;
|
||||
import org.thoughtcrime.securesms.mms.MmsException;
|
||||
import org.thoughtcrime.securesms.mms.OutgoingExpirationUpdateMessage;
|
||||
import org.thoughtcrime.securesms.mms.OutgoingMediaMessage;
|
||||
import org.thoughtcrime.securesms.mms.OutgoingSecureMediaMessage;
|
||||
import org.thoughtcrime.securesms.mms.SlideDeck;
|
||||
import org.thoughtcrime.securesms.mms.StickerSlide;
|
||||
import org.thoughtcrime.securesms.notifications.NotificationChannels;
|
||||
import org.thoughtcrime.securesms.sms.IncomingEncryptedMessage;
|
||||
import org.thoughtcrime.securesms.sms.IncomingEndSessionMessage;
|
||||
import org.thoughtcrime.securesms.sms.IncomingTextMessage;
|
||||
import org.thoughtcrime.securesms.sms.OutgoingEncryptedMessage;
|
||||
import org.thoughtcrime.securesms.sms.OutgoingTextMessage;
|
||||
import org.session.libsignal.utilities.Hex;
|
||||
import org.session.libsignal.libsignal.InvalidMessageException;
|
||||
import org.session.libsignal.libsignal.loki.SessionResetProtocol;
|
||||
import org.session.libsignal.libsignal.state.SignalProtocolStore;
|
||||
import org.session.libsignal.libsignal.util.guava.Optional;
|
||||
import org.session.libsignal.service.api.SignalServiceMessageSender;
|
||||
@@ -111,16 +90,14 @@ import org.session.libsignal.service.api.messages.SignalServiceReceiptMessage;
|
||||
import org.session.libsignal.service.api.messages.SignalServiceTypingMessage;
|
||||
import org.session.libsignal.service.api.messages.shared.SharedContact;
|
||||
import org.session.libsignal.service.api.push.SignalServiceAddress;
|
||||
import org.session.libsignal.service.loki.protocol.mentions.MentionsManager;
|
||||
import org.session.libsignal.service.loki.utilities.mentions.MentionsManager;
|
||||
import org.session.libsignal.service.loki.utilities.PublicKeyValidation;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.security.SecureRandom;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
import javax.inject.Inject;
|
||||
|
||||
@@ -242,10 +219,9 @@ public class PushDecryptJob extends BaseJob implements InjectableType {
|
||||
try {
|
||||
GroupDatabase groupDatabase = DatabaseFactory.getGroupDatabase(context);
|
||||
SignalProtocolStore axolotlStore = new SignalProtocolStoreImpl(context);
|
||||
SessionResetProtocol sessionResetProtocol = new SessionResetImplementation(context);
|
||||
SignalServiceAddress localAddress = new SignalServiceAddress(TextSecurePreferences.getLocalNumber(context));
|
||||
LokiAPIDatabase apiDB = DatabaseFactory.getLokiAPIDatabase(context);
|
||||
SignalServiceCipher cipher = new SignalServiceCipher(localAddress, axolotlStore, sessionResetProtocol, new SessionProtocolImpl(context), apiDB);
|
||||
SignalServiceCipher cipher = new SignalServiceCipher(localAddress, axolotlStore, new SessionProtocolImpl(context), apiDB);
|
||||
|
||||
SignalServiceContent content = cipher.decrypt(envelope);
|
||||
|
||||
@@ -254,8 +230,6 @@ public class PushDecryptJob extends BaseJob implements InjectableType {
|
||||
return;
|
||||
}
|
||||
|
||||
SessionManagementProtocol.handlePreKeyBundleMessageIfNeeded(context, content);
|
||||
|
||||
SessionMetaProtocol.handleProfileUpdateIfNeeded(context, content);
|
||||
|
||||
if (content.configurationMessageProto.isPresent()) {
|
||||
@@ -341,7 +315,6 @@ public class PushDecryptJob extends BaseJob implements InjectableType {
|
||||
}
|
||||
|
||||
if (threadId != null) {
|
||||
SessionManagementProtocol.handleEndSessionMessageIfNeeded(context, content);
|
||||
messageNotifier.updateNotification(context, threadId);
|
||||
}
|
||||
}
|
||||
@@ -706,82 +679,6 @@ public class PushDecryptJob extends BaseJob implements InjectableType {
|
||||
smsDatabase.markAsDecryptFailed(smsMessageId.get());
|
||||
}
|
||||
}
|
||||
|
||||
if (canRecoverAutomatically(e)) {
|
||||
Recipient recipient = Recipient.from(context, Address.fromSerialized(sender), false);
|
||||
LokiThreadDatabase threadDB = DatabaseFactory.getLokiThreadDatabase(context);
|
||||
long threadID = DatabaseFactory.getThreadDatabase(context).getOrCreateThreadIdFor(recipient);
|
||||
threadDB.addSessionRestoreDevice(threadID, sender);
|
||||
SessionManagementProtocol.startSessionReset(context, sender);
|
||||
} else {
|
||||
SessionManagementProtocol.triggerSessionRestorationUI(context, sender, timestamp);
|
||||
}
|
||||
}
|
||||
|
||||
private boolean canRecoverAutomatically(Throwable e) {
|
||||
// Corrupt message exception
|
||||
if (e.getCause() != null) {
|
||||
Throwable e2 = e.getCause();
|
||||
if (e2.getCause() != null) {
|
||||
Throwable e3 = e2.getCause();
|
||||
if (e3 instanceof InvalidMessageException) {
|
||||
String message = e3.getMessage();
|
||||
return (message != null && message.startsWith("Bad Mac!"));
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private void handleNoSessionMessage(@NonNull String sender, int senderDevice, long timestamp,
|
||||
@NonNull Optional<Long> smsMessageId)
|
||||
{
|
||||
SmsDatabase smsDatabase = DatabaseFactory.getSmsDatabase(context);
|
||||
if (!SessionMetaProtocol.shouldIgnoreDecryptionException(context, timestamp)) {
|
||||
if (!smsMessageId.isPresent()) {
|
||||
Optional<InsertResult> insertResult = insertPlaceholder(sender, senderDevice, timestamp);
|
||||
|
||||
if (insertResult.isPresent()) {
|
||||
smsDatabase.markAsNoSession(insertResult.get().getMessageId());
|
||||
messageNotifier.updateNotification(context, insertResult.get().getThreadId());
|
||||
}
|
||||
} else {
|
||||
smsDatabase.markAsNoSession(smsMessageId.get());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void handleLegacyMessage(@NonNull String sender, int senderDevice, long timestamp,
|
||||
@NonNull Optional<Long> smsMessageId)
|
||||
{
|
||||
SmsDatabase smsDatabase = DatabaseFactory.getSmsDatabase(context);
|
||||
|
||||
if (!smsMessageId.isPresent()) {
|
||||
Optional<InsertResult> insertResult = insertPlaceholder(sender, senderDevice, timestamp);
|
||||
|
||||
if (insertResult.isPresent()) {
|
||||
smsDatabase.markAsLegacyVersion(insertResult.get().getMessageId());
|
||||
messageNotifier.updateNotification(context, insertResult.get().getThreadId());
|
||||
}
|
||||
} else {
|
||||
smsDatabase.markAsLegacyVersion(smsMessageId.get());
|
||||
}
|
||||
}
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
private void handleDuplicateMessage(@NonNull String sender, int senderDeviceId, long timestamp,
|
||||
@NonNull Optional<Long> smsMessageId)
|
||||
{
|
||||
// Let's start ignoring these now
|
||||
// SmsDatabase smsDatabase = DatabaseFactory.getEncryptingSmsDatabase(context);
|
||||
//
|
||||
// if (smsMessageId <= 0) {
|
||||
// Pair<Long, Long> messageAndThreadId = insertPlaceholder(masterSecret, envelope);
|
||||
// smsDatabase.markAsDecryptDuplicate(messageAndThreadId.first);
|
||||
// MessageNotifier.updateNotification(context, masterSecret, messageAndThreadId.second);
|
||||
// } else {
|
||||
// smsDatabase.markAsDecryptDuplicate(smsMessageId);
|
||||
// }
|
||||
}
|
||||
|
||||
private void handleNeedsDeliveryReceipt(@NonNull SignalServiceContent content,
|
||||
@@ -905,42 +802,6 @@ public class PushDecryptJob extends BaseJob implements InjectableType {
|
||||
PointerAttachment.forPointersOfDataMessage(quote.get().getAttachments())));
|
||||
}
|
||||
|
||||
private Optional<Attachment> getStickerAttachment(Optional<SignalServiceDataMessage.Sticker> sticker) {
|
||||
if (!sticker.isPresent()) {
|
||||
return Optional.absent();
|
||||
}
|
||||
|
||||
if (sticker.get().getPackId() == null || sticker.get().getPackKey() == null || sticker.get().getAttachment() == null) {
|
||||
Log.w(TAG, "Malformed sticker!");
|
||||
return Optional.absent();
|
||||
}
|
||||
|
||||
String packId = Hex.toStringCondensed(sticker.get().getPackId());
|
||||
String packKey = Hex.toStringCondensed(sticker.get().getPackKey());
|
||||
int stickerId = sticker.get().getStickerId();
|
||||
StickerLocator stickerLocator = new StickerLocator(packId, packKey, stickerId);
|
||||
StickerDatabase stickerDatabase = DatabaseFactory.getStickerDatabase(context);
|
||||
StickerRecord stickerRecord = stickerDatabase.getSticker(stickerLocator.getPackId(), stickerLocator.getStickerId(), false);
|
||||
|
||||
if (stickerRecord != null) {
|
||||
return Optional.of(new UriAttachment(stickerRecord.getUri(),
|
||||
stickerRecord.getUri(),
|
||||
MediaTypes.IMAGE_WEBP,
|
||||
AttachmentDatabase.TRANSFER_PROGRESS_DONE,
|
||||
stickerRecord.getSize(),
|
||||
StickerSlide.WIDTH,
|
||||
StickerSlide.HEIGHT,
|
||||
null,
|
||||
String.valueOf(new SecureRandom().nextLong()),
|
||||
false,
|
||||
false,
|
||||
null,
|
||||
stickerLocator));
|
||||
} else {
|
||||
return Optional.of(PointerAttachment.forPointer(Optional.of(sticker.get().getAttachment()), stickerLocator).get());
|
||||
}
|
||||
}
|
||||
|
||||
private Optional<List<Contact>> getContacts(Optional<List<SharedContact>> sharedContacts) {
|
||||
if (!sharedContacts.isPresent()) return Optional.absent();
|
||||
|
||||
@@ -1069,10 +930,6 @@ public class PushDecryptJob extends BaseJob implements InjectableType {
|
||||
return false;
|
||||
}
|
||||
|
||||
private boolean isGroupChatMessage(SignalServiceContent content) {
|
||||
return content.getDataMessage().isPresent() && content.getDataMessage().get().isGroupMessage();
|
||||
}
|
||||
|
||||
private void resetRecipientToPush(@NonNull Recipient recipient) {
|
||||
if (recipient.isForceSmsSelection()) {
|
||||
DatabaseFactory.getRecipientDatabase(context).setForceSmsSelection(recipient, false);
|
||||
|
@@ -39,12 +39,10 @@ import org.session.libsignal.service.api.messages.SendMessageResult;
|
||||
import org.session.libsignal.service.api.messages.SignalServiceAttachment;
|
||||
import org.session.libsignal.service.api.messages.SignalServiceDataMessage;
|
||||
import org.session.libsignal.service.api.messages.SignalServiceDataMessage.Preview;
|
||||
import org.session.libsignal.service.api.messages.multidevice.SignalServiceSyncMessage;
|
||||
import org.session.libsignal.service.api.messages.shared.SharedContact;
|
||||
import org.session.libsignal.service.api.push.SignalServiceAddress;
|
||||
import org.session.libsignal.service.api.push.exceptions.UnregisteredUserException;
|
||||
import org.session.libsignal.service.loki.api.SnodeAPI;
|
||||
import org.session.libsignal.service.loki.protocol.meta.SessionMetaProtocol;
|
||||
|
||||
import java.io.FileNotFoundException;
|
||||
import java.io.IOException;
|
||||
@@ -285,7 +283,7 @@ public class PushMediaSendJob extends PushSendJob implements InjectableType {
|
||||
.asExpirationUpdate(message.isExpirationUpdate())
|
||||
.build();
|
||||
|
||||
if (SessionMetaProtocol.shared.isNoteToSelf(address.getNumber())) {
|
||||
if (userPublicKey == address.getNumber()) {
|
||||
// Loki - Device link messages don't go through here
|
||||
SendMessageResult result = messageSender.sendMessage(messageId, address, unidentifiedAccessPair, mediaMessage);
|
||||
if (result.getLokiAPIError() != null) {
|
||||
|
@@ -33,10 +33,7 @@ public abstract class PushReceivedJob extends BaseJob {
|
||||
}
|
||||
}
|
||||
|
||||
if (envelope.isReceipt()) {
|
||||
handleReceipt(envelope);
|
||||
} else if (envelope.isPreKeySignalMessage() || envelope.isSignalMessage()
|
||||
|| envelope.isUnidentifiedSender() || envelope.isFallbackMessage() || envelope.isClosedGroupCiphertext()) {
|
||||
if (envelope.isUnidentifiedSender() || envelope.isClosedGroupCiphertext()) {
|
||||
handleMessage(envelope, isPushNotification);
|
||||
} else {
|
||||
Log.w(TAG, "Received envelope of unknown type: " + envelope.getType());
|
||||
@@ -51,13 +48,6 @@ public abstract class PushReceivedJob extends BaseJob {
|
||||
new PushDecryptJob(context).processMessage(envelope, isPushNotification);
|
||||
}
|
||||
|
||||
@SuppressLint("DefaultLocale")
|
||||
private void handleReceipt(SignalServiceEnvelope envelope) {
|
||||
Log.i(TAG, String.format("Received receipt: (XXXXX, %d)", envelope.getTimestamp()));
|
||||
DatabaseFactory.getMmsSmsDatabase(context).incrementDeliveryReceiptCount(new SyncMessageId(Address.fromExternal(context, envelope.getSource()),
|
||||
envelope.getTimestamp()), System.currentTimeMillis());
|
||||
}
|
||||
|
||||
private boolean isActiveNumber(@NonNull Recipient recipient) {
|
||||
return recipient.resolve().getRegistered() == Recipient.RegisteredState.REGISTERED;
|
||||
}
|
||||
|
@@ -12,7 +12,6 @@ import org.session.libsession.messaging.sending_receiving.attachments.Attachment
|
||||
import org.session.libsession.messaging.sending_receiving.sharecontacts.Contact;
|
||||
import org.session.libsession.utilities.MediaTypes;
|
||||
import org.session.libsignal.utilities.Base64;
|
||||
import org.session.libsession.utilities.TextSecurePreferences;
|
||||
import org.session.libsession.utilities.Util;
|
||||
|
||||
import org.greenrobot.eventbus.EventBus;
|
||||
@@ -34,13 +33,10 @@ import org.thoughtcrime.securesms.util.BitmapUtil;
|
||||
import org.session.libsignal.utilities.Hex;
|
||||
import org.thoughtcrime.securesms.util.MediaUtil;
|
||||
import org.session.libsignal.libsignal.util.guava.Optional;
|
||||
import org.session.libsignal.service.api.crypto.UnidentifiedAccessPair;
|
||||
import org.session.libsignal.service.api.messages.SignalServiceAttachment;
|
||||
import org.session.libsignal.service.api.messages.SignalServiceAttachmentPointer;
|
||||
import org.session.libsignal.service.api.messages.SignalServiceDataMessage;
|
||||
import org.session.libsignal.service.api.messages.SignalServiceDataMessage.Preview;
|
||||
import org.session.libsignal.service.api.messages.multidevice.SentTranscriptMessage;
|
||||
import org.session.libsignal.service.api.messages.multidevice.SignalServiceSyncMessage;
|
||||
import org.session.libsignal.service.api.messages.shared.SharedContact;
|
||||
import org.session.libsignal.service.api.push.SignalServiceAddress;
|
||||
|
||||
@@ -55,7 +51,6 @@ import java.util.concurrent.TimeUnit;
|
||||
public abstract class PushSendJob extends SendJob {
|
||||
|
||||
private static final String TAG = PushSendJob.class.getSimpleName();
|
||||
private static final long CERTIFICATE_EXPIRATION_BUFFER = TimeUnit.DAYS.toMillis(1);
|
||||
|
||||
protected PushSendJob(Job.Parameters parameters) {
|
||||
super(parameters);
|
||||
@@ -72,14 +67,6 @@ public abstract class PushSendJob extends SendJob {
|
||||
|
||||
@Override
|
||||
protected final void onSend() throws Exception {
|
||||
// if (TextSecurePreferences.getSignedPreKeyFailureCount(context) > 5) {
|
||||
// ApplicationContext.getInstance(context)
|
||||
// .getJobManager()
|
||||
// .add(new RotateSignedPreKeyJob());
|
||||
//
|
||||
// throw new TextSecureExpiredException("Too many signed prekey rotation failures");
|
||||
// }
|
||||
|
||||
onPushSend();
|
||||
}
|
||||
|
||||
|
@@ -30,11 +30,9 @@ import org.session.libsignal.service.api.crypto.UnidentifiedAccessPair;
|
||||
import org.session.libsignal.service.api.crypto.UntrustedIdentityException;
|
||||
import org.session.libsignal.service.api.messages.SendMessageResult;
|
||||
import org.session.libsignal.service.api.messages.SignalServiceDataMessage;
|
||||
import org.session.libsignal.service.api.messages.multidevice.SignalServiceSyncMessage;
|
||||
import org.session.libsignal.service.api.push.SignalServiceAddress;
|
||||
import org.session.libsignal.service.api.push.exceptions.UnregisteredUserException;
|
||||
import org.session.libsignal.service.loki.api.SnodeAPI;
|
||||
import org.session.libsignal.service.loki.protocol.meta.SessionMetaProtocol;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
@@ -224,7 +222,7 @@ public class PushTextSendJob extends PushSendJob implements InjectableType {
|
||||
.asEndSessionMessage(message.isEndSession())
|
||||
.build();
|
||||
|
||||
if (SessionMetaProtocol.shared.isNoteToSelf(address.getNumber())) {
|
||||
if (userPublicKey.equals(address.getNumber())) {
|
||||
// Loki - Device link messages don't go through here
|
||||
SendMessageResult result = messageSender.sendMessage(messageId, address, unidentifiedAccess, textSecureMessage);
|
||||
if (result.getLokiAPIError() != null) {
|
||||
|
@@ -87,16 +87,14 @@ public class TypingSendJob extends BaseJob implements InjectableType {
|
||||
}
|
||||
|
||||
List<Recipient> recipients = Collections.singletonList(recipient);
|
||||
Optional<byte[]> groupId = Optional.absent();
|
||||
|
||||
if (recipient.isGroupRecipient()) {
|
||||
recipients = DatabaseFactory.getGroupDatabase(context).getGroupMembers(recipient.getAddress().toGroupString(), false);
|
||||
groupId = Optional.of(GroupUtil.getDecodedGroupIDAsData(recipient.getAddress().toGroupString()));
|
||||
}
|
||||
|
||||
List<SignalServiceAddress> addresses = Stream.of(recipients).map(r -> new SignalServiceAddress(r.getAddress().serialize())).toList();
|
||||
List<Optional<UnidentifiedAccessPair>> unidentifiedAccess = Stream.of(recipients).map(r -> UnidentifiedAccessUtil.getAccessFor(context, r)).toList();
|
||||
SignalServiceTypingMessage typingMessage = new SignalServiceTypingMessage(typing ? Action.STARTED : Action.STOPPED, System.currentTimeMillis(), groupId);
|
||||
SignalServiceTypingMessage typingMessage = new SignalServiceTypingMessage(typing ? Action.STARTED : Action.STOPPED, System.currentTimeMillis());
|
||||
|
||||
messageSender.sendTyping(addresses, unidentifiedAccess, typingMessage);
|
||||
}
|
||||
|
@@ -193,8 +193,6 @@ class BackupRestoreViewModel(application: Application): AndroidViewModel(applica
|
||||
application.setUpStorageAPIIfNeeded()
|
||||
application.setUpP2PAPIIfNeeded()
|
||||
|
||||
HomeActivity.requestResetAllSessionsOnStartup(context)
|
||||
|
||||
BackupRestoreResult.SUCCESS
|
||||
} catch (e: DatabaseDowngradeException) {
|
||||
Log.w(TAG, "Failed due to the backup being from a newer version of Signal.", e)
|
||||
|
@@ -33,7 +33,6 @@ import org.session.libsession.utilities.GroupUtil
|
||||
import org.thoughtcrime.securesms.database.DatabaseFactory
|
||||
import org.thoughtcrime.securesms.database.model.ThreadRecord
|
||||
import org.thoughtcrime.securesms.loki.api.ResetThreadSessionJob
|
||||
import org.thoughtcrime.securesms.loki.protocol.SessionResetImplementation
|
||||
import org.thoughtcrime.securesms.loki.utilities.*
|
||||
import org.thoughtcrime.securesms.loki.views.ConversationView
|
||||
import org.thoughtcrime.securesms.loki.views.NewConversationButtonSetViewDelegate
|
||||
@@ -44,8 +43,7 @@ import org.session.libsession.utilities.TextSecurePreferences
|
||||
import org.session.libsession.utilities.TextSecurePreferences.getBooleanPreference
|
||||
import org.session.libsession.utilities.TextSecurePreferences.setBooleanPreference
|
||||
import org.session.libsession.utilities.Util
|
||||
import org.session.libsignal.service.loki.protocol.mentions.MentionsManager
|
||||
import org.session.libsignal.service.loki.protocol.meta.SessionMetaProtocol
|
||||
import org.session.libsignal.service.loki.utilities.mentions.MentionsManager
|
||||
import org.session.libsignal.utilities.ThreadUtils
|
||||
import org.session.libsignal.service.loki.utilities.toHexString
|
||||
import org.thoughtcrime.securesms.loki.dialogs.*
|
||||
@@ -54,31 +52,6 @@ import java.io.IOException
|
||||
|
||||
class HomeActivity : PassphraseRequiredActionBarActivity, ConversationClickListener, SeedReminderViewDelegate, NewConversationButtonSetViewDelegate {
|
||||
|
||||
companion object {
|
||||
private const val PREF_RESET_ALL_SESSIONS_ON_START_UP = "pref_reset_all_sessions_on_start_up"
|
||||
|
||||
@JvmStatic
|
||||
fun requestResetAllSessionsOnStartup(context: Context) {
|
||||
setBooleanPreference(context, PREF_RESET_ALL_SESSIONS_ON_START_UP, true)
|
||||
}
|
||||
|
||||
@JvmStatic
|
||||
fun scheduleResetAllSessionsIfRequested(context: Context) {
|
||||
if (!getBooleanPreference(context, PREF_RESET_ALL_SESSIONS_ON_START_UP, false)) return
|
||||
setBooleanPreference(context, PREF_RESET_ALL_SESSIONS_ON_START_UP, false)
|
||||
|
||||
val jobManager = ApplicationContext.getInstance(context).jobManager
|
||||
|
||||
DatabaseFactory.getThreadDatabase(context).conversationListQuick.forEach { tuple ->
|
||||
val threadId: Long = tuple.first
|
||||
val recipientAddress: String = tuple.second
|
||||
jobManager.add(ResetThreadSessionJob(
|
||||
Address.fromSerialized(recipientAddress),
|
||||
threadId))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private lateinit var glide: GlideRequests
|
||||
private var broadcastReceiver: BroadcastReceiver? = null
|
||||
|
||||
@@ -165,10 +138,8 @@ class HomeActivity : PassphraseRequiredActionBarActivity, ConversationClickListe
|
||||
val threadDB = DatabaseFactory.getLokiThreadDatabase(this)
|
||||
val userDB = DatabaseFactory.getLokiUserDatabase(this)
|
||||
val userPublicKey = TextSecurePreferences.getLocalNumber(this)
|
||||
val sessionResetImpl = SessionResetImplementation(this)
|
||||
if (userPublicKey != null) {
|
||||
MentionsManager.configureIfNeeded(userPublicKey, threadDB, userDB)
|
||||
SessionMetaProtocol.configureIfNeeded(apiDB, userPublicKey)
|
||||
application.publicChatManager.startPollersIfNeeded()
|
||||
}
|
||||
IP2Country.configureIfNeeded(this)
|
||||
|
@@ -153,67 +153,11 @@ class PublicChatPoller(private val context: Context, private val group: PublicCh
|
||||
signalLinkPreviews.add(SignalServiceDataMessage.Preview(linkPreview.linkPreviewURL!!, linkPreview.linkPreviewTitle!!, Optional.of(attachment)))
|
||||
}
|
||||
val body = if (message.body == message.timestamp.toString()) "" else message.body // Workaround for the fact that the back-end doesn't accept messages without a body
|
||||
return SignalServiceDataMessage(message.timestamp, serviceGroup, attachments, body, 0, false, null, quote, null, signalLinkPreviews)
|
||||
val syncTarget = if (message.senderPublicKey == userHexEncodedPublicKey) group.id else null
|
||||
return SignalServiceDataMessage(message.timestamp, serviceGroup, attachments, body, 0, false, null, quote, null, signalLinkPreviews, null, syncTarget)
|
||||
}
|
||||
|
||||
fun pollForNewMessages(): Promise<Unit, Exception> {
|
||||
fun processIncomingMessage(message: PublicChatMessage) {
|
||||
// If the sender of the current message is not a slave device, set the display name in the database
|
||||
val senderDisplayName = "${message.displayName} (...${message.senderPublicKey.takeLast(8)})"
|
||||
DatabaseFactory.getLokiUserDatabase(context).setServerDisplayName(group.id, message.senderPublicKey, senderDisplayName)
|
||||
val senderHexEncodedPublicKey = message.senderPublicKey
|
||||
val serviceDataMessage = getDataMessage(message)
|
||||
val serviceContent = SignalServiceContent(serviceDataMessage, senderHexEncodedPublicKey, SignalServiceAddress.DEFAULT_DEVICE_ID, message.serverTimestamp, 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 {
|
||||
PushDecryptJob(context).handleTextMessage(serviceContent, serviceDataMessage, Optional.absent(), Optional.of(message.serverID))
|
||||
}
|
||||
// Update profile picture if needed
|
||||
val senderAsRecipient = Recipient.from(context, Address.fromSerialized(senderHexEncodedPublicKey), false)
|
||||
if (message.profilePicture != null && message.profilePicture!!.url.isNotEmpty()) {
|
||||
val profileKey = message.profilePicture!!.profileKey
|
||||
val url = message.profilePicture!!.url
|
||||
if (senderAsRecipient.profileKey == null || !MessageDigest.isEqual(senderAsRecipient.profileKey, profileKey)) {
|
||||
val database = DatabaseFactory.getRecipientDatabase(context)
|
||||
database.setProfileKey(senderAsRecipient, profileKey)
|
||||
ApplicationContext.getInstance(context).jobManager.add(RetrieveProfileAvatarJob(senderAsRecipient, url))
|
||||
}
|
||||
}
|
||||
}
|
||||
fun processOutgoingMessage(message: PublicChatMessage) {
|
||||
val messageServerID = message.serverID ?: return
|
||||
val messageID = DatabaseFactory.getLokiMessageDatabase(context).getMessageID(messageServerID)
|
||||
var isDuplicate = false
|
||||
if (messageID != null) {
|
||||
isDuplicate = DatabaseFactory.getMmsDatabase(context).getThreadIdForMessage(messageID) >= 0
|
||||
|| DatabaseFactory.getSmsDatabase(context).getThreadIdForMessage(messageID) >= 0
|
||||
}
|
||||
if (isDuplicate) { return }
|
||||
if (message.body.isEmpty() && message.attachments.isEmpty() && message.quote == null) { return }
|
||||
val userHexEncodedPublicKey = TextSecurePreferences.getLocalNumber(context)
|
||||
val dataMessage = getDataMessage(message)
|
||||
SessionMetaProtocol.dropFromTimestampCacheIfNeeded(message.serverTimestamp)
|
||||
val transcript = SentTranscriptMessage(userHexEncodedPublicKey, message.serverTimestamp, dataMessage, dataMessage.expiresInSeconds.toLong(), Collections.singletonMap(userHexEncodedPublicKey, false))
|
||||
transcript.messageServerID = messageServerID
|
||||
if (dataMessage.quote.isPresent || (dataMessage.attachments.isPresent && dataMessage.attachments.get().size > 0) || dataMessage.previews.isPresent) {
|
||||
PushDecryptJob(context).handleSynchronizeSentMediaMessage(transcript)
|
||||
} else {
|
||||
PushDecryptJob(context).handleSynchronizeSentTextMessage(transcript)
|
||||
}
|
||||
// If we got a message from our master device then make sure our mapping stays in sync
|
||||
val recipient = Recipient.from(context, Address.fromSerialized(message.senderPublicKey), false)
|
||||
if (message.profilePicture != null) {
|
||||
val profileKey = message.profilePicture!!.profileKey
|
||||
val url = message.profilePicture!!.url
|
||||
if (recipient.profileKey == null || !MessageDigest.isEqual(recipient.profileKey, profileKey)) {
|
||||
val database = DatabaseFactory.getRecipientDatabase(context)
|
||||
database.setProfileKey(recipient, profileKey)
|
||||
database.setProfileAvatar(recipient, url)
|
||||
ApplicationContext.getInstance(context).updateOpenGroupProfilePicturesIfNeeded()
|
||||
}
|
||||
}
|
||||
}
|
||||
if (isPollOngoing) { return Promise.of(Unit) }
|
||||
isPollOngoing = true
|
||||
val userPrivateKey = IdentityKeyUtil.getIdentityKeyPair(context).privateKey.serialize()
|
||||
@@ -226,10 +170,27 @@ class PublicChatPoller(private val context: Context, private val group: PublicCh
|
||||
promise.successBackground { messages ->
|
||||
// Process messages in the background
|
||||
messages.forEach { message ->
|
||||
if (message.senderPublicKey == userHexEncodedPublicKey) {
|
||||
processOutgoingMessage(message)
|
||||
// If the sender of the current message is not a slave device, set the display name in the database
|
||||
val senderDisplayName = "${message.displayName} (...${message.senderPublicKey.takeLast(8)})"
|
||||
DatabaseFactory.getLokiUserDatabase(context).setServerDisplayName(group.id, message.senderPublicKey, senderDisplayName)
|
||||
val senderHexEncodedPublicKey = message.senderPublicKey
|
||||
val serviceDataMessage = getDataMessage(message)
|
||||
val serviceContent = SignalServiceContent(serviceDataMessage, senderHexEncodedPublicKey, SignalServiceAddress.DEFAULT_DEVICE_ID, message.serverTimestamp, 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 {
|
||||
processIncomingMessage(message)
|
||||
PushDecryptJob(context).handleTextMessage(serviceContent, serviceDataMessage, Optional.absent(), Optional.of(message.serverID))
|
||||
}
|
||||
// Update profile picture if needed
|
||||
val senderAsRecipient = Recipient.from(context, Address.fromSerialized(senderHexEncodedPublicKey), false)
|
||||
if (message.profilePicture != null && message.profilePicture!!.url.isNotEmpty()) {
|
||||
val profileKey = message.profilePicture!!.profileKey
|
||||
val url = message.profilePicture!!.url
|
||||
if (senderAsRecipient.profileKey == null || !MessageDigest.isEqual(senderAsRecipient.profileKey, profileKey)) {
|
||||
val database = DatabaseFactory.getRecipientDatabase(context)
|
||||
database.setProfileKey(senderAsRecipient, profileKey)
|
||||
ApplicationContext.getInstance(context).jobManager.add(RetrieveProfileAvatarJob(senderAsRecipient, url))
|
||||
}
|
||||
}
|
||||
}
|
||||
isCaughtUp = true
|
||||
|
@@ -14,7 +14,6 @@ import org.session.libsession.messaging.threads.recipients.Recipient
|
||||
import org.session.libsession.utilities.TextSecurePreferences
|
||||
import org.session.libsignal.service.loki.api.opengroups.PublicChat
|
||||
|
||||
import org.session.libsignal.libsignal.loki.SessionResetStatus
|
||||
import org.session.libsignal.utilities.JsonUtil
|
||||
import org.session.libsignal.service.loki.database.LokiThreadDatabaseProtocol
|
||||
import org.session.libsignal.service.loki.utilities.PublicKeyValidation
|
||||
@@ -39,34 +38,6 @@ class LokiThreadDatabase(context: Context, helper: SQLCipherOpenHelper) : Databa
|
||||
return DatabaseFactory.getThreadDatabase(context).getOrCreateThreadIdFor(recipient)
|
||||
}
|
||||
|
||||
fun getThreadID(messageID: Long): Long {
|
||||
return DatabaseFactory.getSmsDatabase(context).getThreadIdForMessage(messageID)
|
||||
}
|
||||
|
||||
fun getSessionResetStatus(hexEncodedPublicKey: String): SessionResetStatus {
|
||||
val threadID = getThreadID(hexEncodedPublicKey)
|
||||
val database = databaseHelper.readableDatabase
|
||||
val result = database.get(sessionResetTable, "${Companion.threadID} = ?", arrayOf( threadID.toString() )) { cursor ->
|
||||
cursor.getInt(sessionResetStatus)
|
||||
}
|
||||
return if (result != null) {
|
||||
SessionResetStatus.values().first { it.rawValue == result }
|
||||
} else {
|
||||
SessionResetStatus.NONE
|
||||
}
|
||||
}
|
||||
|
||||
fun setSessionResetStatus(hexEncodedPublicKey: String, sessionResetStatus: SessionResetStatus) {
|
||||
val threadID = getThreadID(hexEncodedPublicKey)
|
||||
val database = databaseHelper.writableDatabase
|
||||
val contentValues = ContentValues(2)
|
||||
contentValues.put(Companion.threadID, threadID)
|
||||
contentValues.put(Companion.sessionResetStatus, sessionResetStatus.rawValue)
|
||||
database.insertOrUpdate(sessionResetTable, contentValues, "${Companion.threadID} = ?", arrayOf( threadID.toString() ))
|
||||
notifyConversationListListeners()
|
||||
notifyConversationListeners(threadID)
|
||||
}
|
||||
|
||||
fun getAllPublicChats(): Map<Long, PublicChat> {
|
||||
val database = databaseHelper.readableDatabase
|
||||
var cursor: Cursor? = null
|
||||
|
@@ -13,7 +13,7 @@ import org.session.libsignal.libsignal.util.guava.Optional
|
||||
import org.session.libsignal.service.api.push.SignalServiceAddress
|
||||
import org.session.libsignal.service.internal.push.SignalServiceProtos
|
||||
import org.session.libsignal.service.internal.push.SignalServiceProtos.DataMessage
|
||||
import org.session.libsignal.service.loki.protocol.meta.TTLUtilities
|
||||
import org.session.libsignal.service.loki.utilities.TTLUtilities
|
||||
import org.session.libsignal.service.loki.utilities.removing05PrefixIfNeeded
|
||||
import org.session.libsignal.service.loki.utilities.toHexString
|
||||
import org.thoughtcrime.securesms.ApplicationContext
|
||||
@@ -25,7 +25,6 @@ import org.session.libsignal.utilities.logging.Log
|
||||
import org.thoughtcrime.securesms.loki.utilities.recipient
|
||||
import org.session.libsignal.utilities.Hex
|
||||
|
||||
import java.util.*
|
||||
import java.util.concurrent.TimeUnit
|
||||
|
||||
class ClosedGroupUpdateMessageSendJobV2 private constructor(parameters: Parameters, private val destination: String, private val kind: Kind, private val sentTime: Long) : BaseJob(parameters) {
|
||||
|
@@ -8,6 +8,7 @@ import org.session.libsession.utilities.TextSecurePreferences
|
||||
import org.session.libsignal.libsignal.util.guava.Optional
|
||||
import org.session.libsignal.service.api.push.SignalServiceAddress
|
||||
import org.session.libsignal.service.internal.push.SignalServiceProtos
|
||||
import org.session.libsignal.service.internal.push.SignalServiceProtos.DataMessage
|
||||
import org.session.libsignal.service.loki.utilities.removing05PrefixIfNeeded
|
||||
import org.session.libsignal.utilities.Hex
|
||||
import org.session.libsignal.utilities.logging.Log
|
||||
@@ -72,8 +73,8 @@ object MultiDeviceProtocol {
|
||||
for (closedGroup in configurationMessage.closedGroups) {
|
||||
if (allClosedGroupPublicKeys.contains(closedGroup.publicKey)) continue
|
||||
|
||||
val closedGroupUpdate = SignalServiceProtos.ClosedGroupUpdateV2.newBuilder()
|
||||
closedGroupUpdate.type = SignalServiceProtos.ClosedGroupUpdateV2.Type.NEW
|
||||
val closedGroupUpdate = DataMessage.ClosedGroupControlMessage.newBuilder()
|
||||
closedGroupUpdate.type = DataMessage.ClosedGroupControlMessage.Type.NEW
|
||||
closedGroupUpdate.publicKey = ByteString.copyFrom(Hex.fromStringCondensed(closedGroup.publicKey))
|
||||
closedGroupUpdate.name = closedGroup.name
|
||||
val encryptionKeyPair = SignalServiceProtos.KeyPair.newBuilder()
|
||||
|
@@ -1,85 +0,0 @@
|
||||
package org.thoughtcrime.securesms.loki.protocol
|
||||
|
||||
import com.google.protobuf.ByteString
|
||||
import org.session.libsession.messaging.jobs.Data
|
||||
import org.thoughtcrime.securesms.ApplicationContext
|
||||
import org.thoughtcrime.securesms.crypto.UnidentifiedAccessUtil
|
||||
import org.session.libsession.messaging.threads.Address
|
||||
import org.thoughtcrime.securesms.jobmanager.Job
|
||||
import org.thoughtcrime.securesms.jobmanager.impl.NetworkConstraint
|
||||
import org.thoughtcrime.securesms.jobs.BaseJob
|
||||
import org.session.libsignal.utilities.logging.Log
|
||||
import org.session.libsession.messaging.threads.recipients.Recipient
|
||||
import org.session.libsignal.libsignal.util.guava.Optional
|
||||
import org.session.libsignal.service.api.push.SignalServiceAddress
|
||||
import org.session.libsignal.service.internal.push.SignalServiceProtos
|
||||
import org.session.libsignal.service.loki.protocol.meta.TTLUtilities
|
||||
import java.io.IOException
|
||||
import java.security.SecureRandom
|
||||
import java.util.*
|
||||
import java.util.concurrent.TimeUnit
|
||||
|
||||
class NullMessageSendJob private constructor(parameters: Parameters, private val publicKey: String) : BaseJob(parameters) {
|
||||
|
||||
companion object {
|
||||
const val KEY = "NullMessageSendJob"
|
||||
}
|
||||
|
||||
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, Optional.absent())
|
||||
} 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<NullMessageSendJob> {
|
||||
|
||||
override fun create(parameters: Parameters, data: Data): NullMessageSendJob {
|
||||
try {
|
||||
val publicKey = data.getString("publicKey")
|
||||
return NullMessageSendJob(parameters, publicKey)
|
||||
} catch (e: IOException) {
|
||||
throw AssertionError(e)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@@ -1,102 +0,0 @@
|
||||
package org.thoughtcrime.securesms.loki.protocol
|
||||
|
||||
import android.content.Context
|
||||
import org.session.libsignal.utilities.logging.Log
|
||||
import org.thoughtcrime.securesms.ApplicationContext
|
||||
import org.thoughtcrime.securesms.crypto.SecurityEvent
|
||||
import org.thoughtcrime.securesms.crypto.storage.TextSecureSessionStore
|
||||
import org.thoughtcrime.securesms.database.DatabaseFactory
|
||||
import org.thoughtcrime.securesms.loki.utilities.recipient
|
||||
import org.thoughtcrime.securesms.sms.MessageSender
|
||||
import org.thoughtcrime.securesms.sms.OutgoingEndSessionMessage
|
||||
import org.thoughtcrime.securesms.sms.OutgoingTextMessage
|
||||
import org.session.libsession.utilities.TextSecurePreferences
|
||||
import org.session.libsignal.libsignal.loki.SessionResetStatus
|
||||
import org.session.libsignal.service.api.messages.SignalServiceContent
|
||||
import java.util.*
|
||||
|
||||
object SessionManagementProtocol {
|
||||
|
||||
@JvmStatic
|
||||
fun startSessionReset(context: Context, publicKey: String) {
|
||||
val recipient = recipient(context, publicKey)
|
||||
if (recipient.isGroupRecipient) { return }
|
||||
val lokiThreadDB = DatabaseFactory.getLokiThreadDatabase(context)
|
||||
val threadID = DatabaseFactory.getThreadDatabase(context).getOrCreateThreadIdFor(recipient)
|
||||
val devices = lokiThreadDB.getSessionRestoreDevices(threadID)
|
||||
for (device in devices) {
|
||||
val endSessionMessage = OutgoingEndSessionMessage(OutgoingTextMessage(recipient, "TERMINATE", 0, -1))
|
||||
MessageSender.send(context, endSessionMessage, threadID, false, null)
|
||||
}
|
||||
val smsDB = DatabaseFactory.getSmsDatabase(context)
|
||||
val infoMessage = OutgoingTextMessage(recipient, "", 0, 0)
|
||||
val infoMessageID = smsDB.insertMessageOutbox(threadID, infoMessage, false, System.currentTimeMillis(), null)
|
||||
if (infoMessageID > -1) {
|
||||
smsDB.markAsSentLokiSessionRestorationRequest(infoMessageID)
|
||||
}
|
||||
lokiThreadDB.removeAllSessionRestoreDevices(threadID)
|
||||
}
|
||||
|
||||
// @JvmStatic
|
||||
// fun refreshSignedPreKey(context: Context) {
|
||||
// if (TextSecurePreferences.isSignedPreKeyRegistered(context)) {
|
||||
// Log.d("Loki", "Skipping signed pre key refresh; using existing signed pre key.")
|
||||
// } else {
|
||||
// Log.d("Loki", "Signed pre key refreshed successfully.")
|
||||
// val identityKeyPair = IdentityKeyUtil.getIdentityKeyPair(context)
|
||||
// PreKeyUtil.generateSignedPreKey(context, identityKeyPair, true)
|
||||
// TextSecurePreferences.setSignedPreKeyRegistered(context, true)
|
||||
// ApplicationContext.getInstance(context).jobManager.add(CleanPreKeysJob())
|
||||
// }
|
||||
// }
|
||||
|
||||
@JvmStatic
|
||||
fun shouldProcessSessionRequest(context: Context, publicKey: String, timestamp: Long): Boolean {
|
||||
val apiDB = DatabaseFactory.getLokiAPIDatabase(context)
|
||||
val sentTimestamp = apiDB.getSessionRequestSentTimestamp(publicKey) ?: 0
|
||||
val processedTimestamp = apiDB.getSessionRequestProcessedTimestamp(publicKey) ?: 0
|
||||
val restorationTimestamp = TextSecurePreferences.getRestorationTime(context)
|
||||
return timestamp > sentTimestamp && timestamp > processedTimestamp && timestamp > restorationTimestamp
|
||||
}
|
||||
|
||||
@JvmStatic
|
||||
fun handlePreKeyBundleMessageIfNeeded(context: Context, content: SignalServiceContent) {
|
||||
val preKeyBundleMessage = content.preKeyBundleMessage.orNull() ?: return
|
||||
val publicKey = content.sender
|
||||
if (recipient(context, publicKey).isGroupRecipient) { return } // Should never occur
|
||||
Log.d("Loki", "Received a pre key bundle from: $publicKey.")
|
||||
if (!shouldProcessSessionRequest(context, publicKey, content.timestamp)) {
|
||||
Log.d("Loki", "Ignoring session request from: $publicKey.")
|
||||
return
|
||||
}
|
||||
val registrationID = TextSecurePreferences.getLocalRegistrationId(context)
|
||||
// val lokiPreKeyBundleDatabase = DatabaseFactory.getLokiPreKeyBundleDatabase(context)
|
||||
val preKeyBundle = preKeyBundleMessage.getPreKeyBundle(registrationID)
|
||||
// lokiPreKeyBundleDatabase.setPreKeyBundle(publicKey, preKeyBundle)
|
||||
DatabaseFactory.getLokiAPIDatabase(context).setSessionRequestProcessedTimestamp(publicKey, Date().time)
|
||||
val job = NullMessageSendJob(publicKey)
|
||||
ApplicationContext.getInstance(context).jobManager.add(job)
|
||||
}
|
||||
|
||||
@JvmStatic
|
||||
fun handleEndSessionMessageIfNeeded(context: Context, content: SignalServiceContent) {
|
||||
if (!content.dataMessage.isPresent || !content.dataMessage.get().isEndSession) { return }
|
||||
val sessionStore = TextSecureSessionStore(context)
|
||||
val lokiThreadDB = DatabaseFactory.getLokiThreadDatabase(context)
|
||||
Log.d("Loki", "Received a session reset request from: ${content.sender}; archiving the session.")
|
||||
sessionStore.archiveAllSessions(content.sender)
|
||||
lokiThreadDB.setSessionResetStatus(content.sender, SessionResetStatus.REQUEST_RECEIVED)
|
||||
Log.d("Loki", "Sending an ephemeral message back to: ${content.sender}.")
|
||||
val job = NullMessageSendJob(content.sender)
|
||||
ApplicationContext.getInstance(context).jobManager.add(job)
|
||||
SecurityEvent.broadcastSecurityUpdateEvent(context)
|
||||
}
|
||||
|
||||
@JvmStatic
|
||||
fun triggerSessionRestorationUI(context: Context, publicKey: String, errorTimestamp: Long) {
|
||||
val recipient = recipient(context, publicKey)
|
||||
if (recipient.isGroupRecipient) { return }
|
||||
val threadID = DatabaseFactory.getThreadDatabase(context).getOrCreateThreadIdFor(recipient)
|
||||
DatabaseFactory.getLokiThreadDatabase(context).addSessionRestoreDevice(threadID, publicKey)
|
||||
}
|
||||
}
|
@@ -1,43 +0,0 @@
|
||||
package org.thoughtcrime.securesms.loki.protocol
|
||||
|
||||
import android.content.Context
|
||||
import org.thoughtcrime.securesms.ApplicationContext
|
||||
import org.session.libsession.messaging.threads.Address
|
||||
import org.thoughtcrime.securesms.database.DatabaseFactory
|
||||
import org.session.libsession.messaging.threads.recipients.Recipient
|
||||
import org.thoughtcrime.securesms.sms.OutgoingTextMessage
|
||||
import org.session.libsignal.libsignal.loki.SessionResetProtocol
|
||||
import org.session.libsignal.libsignal.loki.SessionResetStatus
|
||||
import org.session.libsignal.libsignal.protocol.PreKeySignalMessage
|
||||
|
||||
class SessionResetImplementation(private val context: Context) : SessionResetProtocol {
|
||||
|
||||
override fun getSessionResetStatus(publicKey: String): SessionResetStatus {
|
||||
return DatabaseFactory.getLokiThreadDatabase(context).getSessionResetStatus(publicKey)
|
||||
}
|
||||
|
||||
override fun setSessionResetStatus(publicKey: String, sessionResetStatus: SessionResetStatus) {
|
||||
return DatabaseFactory.getLokiThreadDatabase(context).setSessionResetStatus(publicKey, sessionResetStatus)
|
||||
}
|
||||
|
||||
override fun onNewSessionAdopted(publicKey: String, oldSessionResetStatus: SessionResetStatus) {
|
||||
if (oldSessionResetStatus == SessionResetStatus.IN_PROGRESS) {
|
||||
val job = NullMessageSendJob(publicKey)
|
||||
ApplicationContext.getInstance(context).jobManager.add(job)
|
||||
}
|
||||
val smsDB = DatabaseFactory.getSmsDatabase(context)
|
||||
val recipient = Recipient.from(context, Address.fromSerialized(publicKey), false)
|
||||
val threadID = DatabaseFactory.getThreadDatabase(context).getOrCreateThreadIdFor(recipient)
|
||||
val infoMessage = OutgoingTextMessage(recipient, "", 0, 0)
|
||||
val infoMessageID = smsDB.insertMessageOutbox(threadID, infoMessage, false, System.currentTimeMillis(), null)
|
||||
if (infoMessageID > -1) {
|
||||
smsDB.markAsLokiSessionRestorationDone(infoMessageID)
|
||||
}
|
||||
}
|
||||
|
||||
override fun validatePreKeySignalMessage(publicKey: String, message: PreKeySignalMessage) {
|
||||
// val preKeyRecord = DatabaseFactory.getLokiPreKeyRecordDatabase(context).getPreKeyRecord(publicKey) ?: return
|
||||
// // TODO: Checking that the pre key record isn't null is causing issues when it shouldn't
|
||||
// check(preKeyRecord.id == (message.preKeyId ?: -1)) { "Received a background message from an unknown source." }
|
||||
}
|
||||
}
|
@@ -4,7 +4,7 @@ import android.content.Context
|
||||
import org.thoughtcrime.securesms.database.DatabaseFactory
|
||||
import org.thoughtcrime.securesms.database.model.MessageRecord
|
||||
import org.session.libsession.utilities.TextSecurePreferences
|
||||
import org.session.libsignal.service.loki.protocol.mentions.MentionsManager
|
||||
import org.session.libsignal.service.loki.utilities.mentions.MentionsManager
|
||||
|
||||
object MentionManagerUtilities {
|
||||
|
||||
|
@@ -15,8 +15,6 @@ import org.thoughtcrime.securesms.loki.utilities.MentionManagerUtilities.populat
|
||||
import org.thoughtcrime.securesms.loki.utilities.MentionUtilities.highlightMentions
|
||||
import org.thoughtcrime.securesms.mms.GlideRequests
|
||||
import org.thoughtcrime.securesms.util.DateUtils
|
||||
import org.session.libsession.utilities.TextSecurePreferences
|
||||
import org.session.libsignal.service.loki.protocol.mentions.MentionsManager
|
||||
import java.util.*
|
||||
|
||||
class ConversationView : LinearLayout {
|
||||
|
@@ -10,7 +10,7 @@ import android.widget.ListView
|
||||
import org.thoughtcrime.securesms.database.DatabaseFactory
|
||||
import org.thoughtcrime.securesms.loki.utilities.toPx
|
||||
import org.thoughtcrime.securesms.mms.GlideRequests
|
||||
import org.session.libsignal.service.loki.protocol.mentions.Mention
|
||||
import org.session.libsignal.service.loki.utilities.mentions.Mention
|
||||
|
||||
class MentionCandidateSelectionView(context: Context, attrs: AttributeSet?, defStyleAttr: Int) : ListView(context, attrs, defStyleAttr) {
|
||||
private var mentionCandidates = listOf<Mention>()
|
||||
|
@@ -10,7 +10,7 @@ import kotlinx.android.synthetic.main.view_mention_candidate.view.*
|
||||
import network.loki.messenger.R
|
||||
import org.thoughtcrime.securesms.mms.GlideRequests
|
||||
import org.session.libsignal.service.loki.api.opengroups.PublicChatAPI
|
||||
import org.session.libsignal.service.loki.protocol.mentions.Mention
|
||||
import org.session.libsignal.service.loki.utilities.mentions.Mention
|
||||
|
||||
class MentionCandidateView(context: Context, attrs: AttributeSet?, defStyleAttr: Int) : LinearLayout(context, attrs, defStyleAttr) {
|
||||
var mentionCandidate = Mention("", "")
|
||||
|
@@ -17,7 +17,7 @@ import org.thoughtcrime.securesms.loki.utilities.AvatarPlaceholderGenerator
|
||||
import org.thoughtcrime.securesms.mms.GlideRequests
|
||||
import org.session.libsession.messaging.threads.recipients.Recipient
|
||||
import org.session.libsession.utilities.TextSecurePreferences
|
||||
import org.session.libsignal.service.loki.protocol.mentions.MentionsManager
|
||||
import org.session.libsignal.service.loki.utilities.mentions.MentionsManager
|
||||
|
||||
// TODO: Look into a better way of handling different sizes. Maybe an enum (with associated values) encapsulating the different modes?
|
||||
|
||||
|
@@ -83,7 +83,6 @@ public class ExpiringMessageManager implements SSKEnvironment.MessageExpirationM
|
||||
Optional.absent(),
|
||||
Optional.absent(),
|
||||
Optional.absent(),
|
||||
Optional.absent(),
|
||||
Optional.absent());
|
||||
|
||||
database.insertSecureDecryptedMessageInbox(mediaMessage, -1);
|
||||
|
Reference in New Issue
Block a user