diff --git a/src/org/thoughtcrime/securesms/jobs/PushDecryptJob.java b/src/org/thoughtcrime/securesms/jobs/PushDecryptJob.java index 70b748653e..0fa54252fe 100644 --- a/src/org/thoughtcrime/securesms/jobs/PushDecryptJob.java +++ b/src/org/thoughtcrime/securesms/jobs/PushDecryptJob.java @@ -59,7 +59,7 @@ import org.thoughtcrime.securesms.loki.LokiMessageDatabase; import org.thoughtcrime.securesms.loki.LokiPreKeyBundleDatabase; import org.thoughtcrime.securesms.loki.LokiPreKeyRecordDatabase; import org.thoughtcrime.securesms.loki.LokiThreadDatabase; -import org.thoughtcrime.securesms.loki.UtilitiesKt; +import org.thoughtcrime.securesms.loki.MultiDeviceUtilKt; import org.thoughtcrime.securesms.mms.IncomingMediaMessage; import org.thoughtcrime.securesms.mms.MmsException; import org.thoughtcrime.securesms.mms.OutgoingExpirationUpdateMessage; @@ -130,7 +130,6 @@ import javax.inject.Inject; import kotlin.Unit; import network.loki.messenger.R; -import nl.komponents.kovenant.Promise; public class PushDecryptJob extends BaseJob implements InjectableType { @@ -1147,7 +1146,7 @@ public class PushDecryptJob extends BaseJob implements InjectableType { if (!envelope.isFriendRequest()) { return; } // This handles the case where another user sends us a regular message without the authorisation - UtilitiesKt.shouldAutomaticallyBecomeFriendsWithDevice(content.getSender(), context).success(becomeFriends -> { + MultiDeviceUtilKt.shouldAutomaticallyBecomeFriendsWithDevice(content.getSender(), context).success(becomeFriends -> { if (becomeFriends) { // Become friends AND update the message they sent becomeFriendsWithContact(content.getSender()); diff --git a/src/org/thoughtcrime/securesms/loki/Utilities.kt b/src/org/thoughtcrime/securesms/loki/MultiDeviceUtil.kt similarity index 84% rename from src/org/thoughtcrime/securesms/loki/Utilities.kt rename to src/org/thoughtcrime/securesms/loki/MultiDeviceUtil.kt index 4735a74af3..41b0172f9f 100644 --- a/src/org/thoughtcrime/securesms/loki/Utilities.kt +++ b/src/org/thoughtcrime/securesms/loki/MultiDeviceUtil.kt @@ -5,9 +5,12 @@ import android.os.Handler import android.os.Looper import nl.komponents.kovenant.Promise import nl.komponents.kovenant.deferred +import nl.komponents.kovenant.functional.map import org.thoughtcrime.securesms.ApplicationContext import org.thoughtcrime.securesms.database.Address import org.thoughtcrime.securesms.database.DatabaseFactory +import org.thoughtcrime.securesms.jobs.BaseJob +import org.thoughtcrime.securesms.jobs.PushTextSendJob import org.thoughtcrime.securesms.logging.Log import org.thoughtcrime.securesms.recipients.Recipient import org.thoughtcrime.securesms.util.TextSecurePreferences @@ -22,21 +25,22 @@ import org.whispersystems.signalservice.loki.api.LokiPairingAuthorisation import org.whispersystems.signalservice.loki.api.LokiStorageAPI import org.whispersystems.signalservice.loki.messaging.LokiThreadFriendRequestStatus -fun isGroupChat(pubKey: String): Boolean { - return (LokiGroupChatAPI.publicChatServer == pubKey) -} +fun getAllDevices(context: Context, pubKey: String, storageAPI: LokiStorageAPI, block: (devicePubKey: String, isFriend: Boolean, friendCount: Int) -> Unit) { + val ourPubKey = TextSecurePreferences.getLocalNumber(context) -fun getFriends(context: Context, devices: Set): Set { - val lokiThreadDatabase = DatabaseFactory.getLokiThreadDatabase(context) + // Get all the devices and run our logic on them + storageAPI.getAllDevices(pubKey).success { items -> + val devices = items.toMutableSet() + // Remove our self if we intended this message to go to another recipient + if (pubKey != ourPubKey) { + devices.remove(ourPubKey) + } - return devices.mapNotNull { device -> - val address = Address.fromSerialized(device) - val recipient = Recipient.from(context, address, false) - val threadID = DatabaseFactory.getThreadDatabase(context).getThreadIdIfExistsFor(recipient) - if (threadID < 0) { return@mapNotNull null } - - if (lokiThreadDatabase.getFriendRequestStatus(threadID) == LokiThreadFriendRequestStatus.FRIENDS) device else null - }.toSet() + val friends = getFriends(context, devices) + for (device in devices) { + block(device, friends.contains(device), friends.count()) + } + } } fun shouldAutomaticallyBecomeFriendsWithDevice(pubKey: String, context: Context): Promise { diff --git a/src/org/thoughtcrime/securesms/loki/Util.kt b/src/org/thoughtcrime/securesms/loki/Util.kt new file mode 100644 index 0000000000..9f4e2d50e0 --- /dev/null +++ b/src/org/thoughtcrime/securesms/loki/Util.kt @@ -0,0 +1,25 @@ +package org.thoughtcrime.securesms.loki + +import android.content.Context +import org.thoughtcrime.securesms.database.Address +import org.thoughtcrime.securesms.database.DatabaseFactory +import org.thoughtcrime.securesms.recipients.Recipient +import org.whispersystems.signalservice.loki.api.LokiGroupChatAPI +import org.whispersystems.signalservice.loki.messaging.LokiThreadFriendRequestStatus + +fun isGroupChat(pubKey: String): Boolean { + return (LokiGroupChatAPI.publicChatServer == pubKey) +} + +fun getFriends(context: Context, devices: Set): Set { + val lokiThreadDatabase = DatabaseFactory.getLokiThreadDatabase(context) + + return devices.mapNotNull { device -> + val address = Address.fromSerialized(device) + val recipient = Recipient.from(context, address, false) + val threadID = DatabaseFactory.getThreadDatabase(context).getThreadIdIfExistsFor(recipient) + if (threadID < 0) { return@mapNotNull null } + + if (lokiThreadDatabase.getFriendRequestStatus(threadID) == LokiThreadFriendRequestStatus.FRIENDS) device else null + }.toSet() +} \ No newline at end of file diff --git a/src/org/thoughtcrime/securesms/sms/MessageSender.java b/src/org/thoughtcrime/securesms/sms/MessageSender.java index 3fe3c4a5a4..3992653c55 100644 --- a/src/org/thoughtcrime/securesms/sms/MessageSender.java +++ b/src/org/thoughtcrime/securesms/sms/MessageSender.java @@ -42,7 +42,8 @@ import org.thoughtcrime.securesms.jobs.SmsSendJob; import org.thoughtcrime.securesms.linkpreview.LinkPreviewRepository; import org.thoughtcrime.securesms.linkpreview.LinkPreviewUtil; import org.thoughtcrime.securesms.logging.Log; -import org.thoughtcrime.securesms.loki.UtilitiesKt; +import org.thoughtcrime.securesms.loki.MultiDeviceUtilKt; +import org.thoughtcrime.securesms.loki.UtilKt; import org.thoughtcrime.securesms.mms.MmsException; import org.thoughtcrime.securesms.mms.OutgoingMediaMessage; import org.thoughtcrime.securesms.push.AccountManagerFactory; @@ -57,9 +58,6 @@ import org.whispersystems.signalservice.loki.api.LokiStorageAPI; import org.whispersystems.signalservice.loki.messaging.LokiMessageFriendRequestStatus; import java.io.IOException; -import java.util.ArrayList; -import java.util.HashSet; -import java.util.Set; import kotlin.Unit; @@ -213,40 +211,27 @@ public class MessageSender { LokiStorageAPI storageAPI = LokiStorageAPI.Companion.getShared(); JobManager jobManager = ApplicationContext.getInstance(context).getJobManager(); - // Just send the message normally if the job manager failed or if it's a group message + // Just send the message normally if the storage api is not set or if it's a group message String recipientPubKey = recipient.getAddress().serialize(); - if (storageAPI == null || UtilitiesKt.isGroupChat(recipientPubKey)) { + if (storageAPI == null || UtilKt.isGroupChat(recipientPubKey)) { + if (storageAPI == null) { Log.w("Loki", "LokiStorageAPI is not initialized!"); } jobManager.add(new PushTextSendJob(messageId, recipient.getAddress())); return; } - String ourPubKey = TextSecurePreferences.getLocalNumber(context); - - // Get all the devices and run our logic on them - storageAPI.getAllDevices(recipientPubKey).success(devices -> { - // Remove our self if we intended this message to go to another recipient - if (!recipientPubKey.equals(ourPubKey)) { devices.remove(ourPubKey); } - - Set friends = UtilitiesKt.getFriends(context, devices); - Set nonFriends = new HashSet<>(devices); - nonFriends.removeAll(friends); + MultiDeviceUtilKt.getAllDevices(context, recipientPubKey, storageAPI, (devicePubKey, isFriend, friendCount) -> { + Address deviceAddress = Address.fromSerialized(devicePubKey); + long messageIdToUse = recipientPubKey.equals(devicePubKey) ? messageId : -1L; // Send a normal message to our friends - for (String friend : friends) { - // If this message had the same recipient then point it to the correct message id otherwise point it to a non-existing message - long messageIdToUse = recipientPubKey.equals(friend) ? messageId : -1L; - jobManager.add(new PushTextSendJob(messageId, messageIdToUse, Address.fromSerialized(friend))); - } - - // Send friend requests to non friends - for (String stranger : nonFriends) { - // If this message had the same recipient then point it to the correct message id otherwise point it to a non-existing message - long messageIdToUse = recipientPubKey.equals(stranger) ? messageId : -1L; - + if (isFriend) { + jobManager.add(new PushTextSendJob(messageId, messageIdToUse, deviceAddress)); + } else { + // Send friend requests to non friends // If we're friends with one of the devices then send out a default friend request message - boolean isFriendsWithAny = friends.size() > 0; + boolean isFriendsWithAny = friendCount > 0; String defaultFriendRequestMessage = isFriendsWithAny ? "This is a friend request for devices linked to " + recipientPubKey : null; - jobManager.add(new PushTextSendJob(messageId, messageIdToUse, Address.fromSerialized(stranger), true, defaultFriendRequestMessage)); + jobManager.add(new PushTextSendJob(messageId, messageIdToUse, deviceAddress, true, defaultFriendRequestMessage)); } return Unit.INSTANCE;