diff --git a/src/org/thoughtcrime/securesms/conversation/ConversationActivity.java b/src/org/thoughtcrime/securesms/conversation/ConversationActivity.java index f09cf1d7aa..3cac1101ae 100644 --- a/src/org/thoughtcrime/securesms/conversation/ConversationActivity.java +++ b/src/org/thoughtcrime/securesms/conversation/ConversationActivity.java @@ -3007,13 +3007,10 @@ public class ConversationActivity extends PassphraseRequiredActionBarActivity long threadId = originalThreadID < 0 ? this.threadId : originalThreadID; String contactID = DatabaseFactory.getThreadDatabase(this).getRecipientForThreadId(threadId).getAddress().toString(); - SignalServiceMessageSender messageSender = ApplicationContext.getInstance(this).communicationModule.provideSignalMessageSender(); - SignalServiceAddress address = new SignalServiceAddress(contactID); - SignalServiceDataMessage message = new SignalServiceDataMessage(System.currentTimeMillis(), ""); Context context = this; AsyncTask.execute(() -> { try { - messageSender.sendMessage(0, address, Optional.absent(), message); // The message ID doesn't matter + MessageSender.sendBackgroundMessageToAllDevices(this, contactID); DatabaseFactory.getLokiThreadDatabase(context).setFriendRequestStatus(threadId, LokiThreadFriendRequestStatus.FRIENDS); lokiMessageDatabase.setFriendRequestStatus(friendRequest.id, LokiMessageFriendRequestStatus.REQUEST_ACCEPTED); Util.runOnMain(this::updateInputPanel); diff --git a/src/org/thoughtcrime/securesms/jobs/PushDecryptJob.java b/src/org/thoughtcrime/securesms/jobs/PushDecryptJob.java index bccaad08a5..aaa222bec4 100644 --- a/src/org/thoughtcrime/securesms/jobs/PushDecryptJob.java +++ b/src/org/thoughtcrime/securesms/jobs/PushDecryptJob.java @@ -87,6 +87,7 @@ import org.thoughtcrime.securesms.service.WebRtcCallService; import org.thoughtcrime.securesms.sms.IncomingEncryptedMessage; import org.thoughtcrime.securesms.sms.IncomingEndSessionMessage; import org.thoughtcrime.securesms.sms.IncomingTextMessage; +import org.thoughtcrime.securesms.sms.MessageSender; import org.thoughtcrime.securesms.sms.OutgoingEncryptedMessage; import org.thoughtcrime.securesms.sms.OutgoingEndSessionMessage; import org.thoughtcrime.securesms.sms.OutgoingTextMessage; @@ -524,7 +525,7 @@ public class PushDecryptJob extends BaseJob implements InjectableType { Log.d("Loki", "Sending a ping back to " + content.getSender() + "."); String contactID = DatabaseFactory.getThreadDatabase(context).getRecipientForThreadId(threadId).getAddress().toString(); - sendBackgroundMessage(contactID); + MessageSender.sendBackgroundMessage(context, contactID); SecurityEvent.broadcastSecurityUpdateEvent(context); MessageNotifier.updateNotification(context, threadId); @@ -1053,7 +1054,7 @@ public class PushDecryptJob extends BaseJob implements InjectableType { DatabaseFactory.getLokiAPIDatabase(context).insertOrUpdatePairingAuthorisation(authorisation); TextSecurePreferences.setMasterHexEncodedPublicKey(context, authorisation.getPrimaryDevicePublicKey()); // Send a background message to the primary device - sendBackgroundMessage(authorisation.getPrimaryDevicePublicKey()); + MessageSender.sendBackgroundMessage(context, authorisation.getPrimaryDevicePublicKey()); // Propagate the updates to the file server LokiStorageAPI storageAPI = LokiStorageAPI.Companion.getShared(); storageAPI.updateUserDeviceMappings(); @@ -1109,7 +1110,7 @@ public class PushDecryptJob extends BaseJob implements InjectableType { // Become friends AND update the message they sent becomeFriendsWithContact(content.getSender()); // Send them an accept message back - sendBackgroundMessage(content.getSender()); + MessageSender.sendBackgroundMessage(context, content.getSender()); } else { // Do regular friend request logic checks Recipient originalRecipient = getMessageDestination(content, message); @@ -1139,7 +1140,7 @@ public class PushDecryptJob extends BaseJob implements InjectableType { long messageID = smsMessageDatabase.getIDForMessageAtIndex(primaryDeviceThreadID, messageCount - 2); // The message before the one that was just received lokiMessageDatabase.setFriendRequestStatus(messageID, LokiMessageFriendRequestStatus.REQUEST_ACCEPTED); // Accept the friend request - sendBackgroundMessage(content.getSender()); + MessageSender.sendBackgroundMessage(context, content.getSender()); } else if (threadFriendRequestStatus != LokiThreadFriendRequestStatus.FRIENDS) { // Checking that the sender of the message isn't already a friend is necessary because otherwise // the following situation can occur: Alice and Bob are friends. Bob loses his database and his @@ -1155,19 +1156,6 @@ public class PushDecryptJob extends BaseJob implements InjectableType { } } - private void sendBackgroundMessage(String contactHexEncodedPublicKey) { - Util.runOnMain(() -> { - SignalServiceMessageSender messageSender = ApplicationContext.getInstance(context).communicationModule.provideSignalMessageSender(); - SignalServiceAddress address = new SignalServiceAddress(contactHexEncodedPublicKey); - SignalServiceDataMessage message = new SignalServiceDataMessage(System.currentTimeMillis(), ""); - try { - messageSender.sendMessage(0, address, Optional.absent(), message); // The message ID doesn't matter - } catch (Exception e) { - Log.d("Loki", "Failed to send background message to: " + contactHexEncodedPublicKey + "."); - } - }); - } - private long handleSynchronizeSentTextMessage(@NonNull SentTranscriptMessage message) throws MmsException { diff --git a/src/org/thoughtcrime/securesms/sms/MessageSender.java b/src/org/thoughtcrime/securesms/sms/MessageSender.java index de26203e64..1dd43d402f 100644 --- a/src/org/thoughtcrime/securesms/sms/MessageSender.java +++ b/src/org/thoughtcrime/securesms/sms/MessageSender.java @@ -54,12 +54,15 @@ import org.thoughtcrime.securesms.util.TextSecurePreferences; import org.thoughtcrime.securesms.util.Util; import org.whispersystems.libsignal.util.guava.Optional; import org.whispersystems.signalservice.api.SignalServiceAccountManager; +import org.whispersystems.signalservice.api.SignalServiceMessageSender; +import org.whispersystems.signalservice.api.messages.SignalServiceDataMessage; import org.whispersystems.signalservice.api.push.ContactTokenDetails; +import org.whispersystems.signalservice.api.push.SignalServiceAddress; import org.whispersystems.signalservice.loki.api.LokiStorageAPI; import org.whispersystems.signalservice.loki.messaging.LokiMessageFriendRequestStatus; +import org.whispersystems.signalservice.loki.messaging.LokiThreadFriendRequestStatus; import java.io.IOException; -import java.util.function.Function; import kotlin.Unit; @@ -67,6 +70,45 @@ public class MessageSender { private static final String TAG = MessageSender.class.getSimpleName(); + public static void sendBackgroundMessageToAllDevices(Context context, String contactHexEncodedPublicKey) { + // Send the background message to the original pubkey + sendBackgroundMessage(context, contactHexEncodedPublicKey); + + // Go through the other devices and only send background messages if we're friends or we have received friend request + LokiStorageAPI storageAPI = LokiStorageAPI.Companion.getShared(); + storageAPI.getAllDevicePublicKeys(contactHexEncodedPublicKey).success(devices -> { + for (String device : devices) { + // Don't send message to the device we already have sent to + if (device.equals(contactHexEncodedPublicKey)) { continue; } + Recipient recipient = Recipient.from(context, Address.fromSerialized(device), false); + long threadID = DatabaseFactory.getThreadDatabase(context).getThreadIdIfExistsFor(recipient); + if (threadID < 0) { continue; } + LokiThreadFriendRequestStatus friendRequestStatus = DatabaseFactory.getLokiThreadDatabase(context).getFriendRequestStatus(threadID); + if (friendRequestStatus == LokiThreadFriendRequestStatus.FRIENDS || friendRequestStatus == LokiThreadFriendRequestStatus.REQUEST_RECEIVED) { + sendBackgroundMessage(context, device); + } + + // TODO: Do we want to send a custom FR Message if we're not friends and we haven't received a friend request? + } + + return Unit.INSTANCE; + }); + } + + public static void sendBackgroundMessage(Context context, String contactHexEncodedPublicKey) { + Util.runOnMain(() -> { + SignalServiceMessageSender messageSender = ApplicationContext.getInstance(context).communicationModule.provideSignalMessageSender(); + SignalServiceAddress address = new SignalServiceAddress(contactHexEncodedPublicKey); + SignalServiceDataMessage message = new SignalServiceDataMessage(System.currentTimeMillis(), ""); + try { + // Try send to the original person + messageSender.sendMessage(0, address, Optional.absent(), message); // The message ID doesn't matter + } catch (Exception e) { + Log.d("Loki", "Failed to send background message to: " + contactHexEncodedPublicKey + "."); + } + }); + } + public static long send(final Context context, final OutgoingTextMessage message, final long threadId,