From 6f2a6f7f94c49f08fe5b39cab4f92911a9155b64 Mon Sep 17 00:00:00 2001 From: Mikunj Date: Mon, 4 Nov 2019 13:46:36 +1100 Subject: [PATCH] Sync contact upon accepting friend request --- .../conversation/ConversationActivity.java | 14 ++++------ .../securesms/jobs/PushDecryptJob.java | 6 +++-- .../securesms/loki/MultiDeviceUtilities.kt | 4 +-- .../securesms/sms/MessageSender.java | 27 ++++++++++++++----- 4 files changed, 30 insertions(+), 21 deletions(-) diff --git a/src/org/thoughtcrime/securesms/conversation/ConversationActivity.java b/src/org/thoughtcrime/securesms/conversation/ConversationActivity.java index d9ec0a0154..c682afcb62 100644 --- a/src/org/thoughtcrime/securesms/conversation/ConversationActivity.java +++ b/src/org/thoughtcrime/securesms/conversation/ConversationActivity.java @@ -127,7 +127,6 @@ import org.thoughtcrime.securesms.contactshare.SimpleTextWatcher; import org.thoughtcrime.securesms.crypto.IdentityKeyParcelable; import org.thoughtcrime.securesms.crypto.SecurityEvent; import org.thoughtcrime.securesms.database.Address; -import org.thoughtcrime.securesms.database.Database; import org.thoughtcrime.securesms.database.DatabaseFactory; import org.thoughtcrime.securesms.database.DraftDatabase; import org.thoughtcrime.securesms.database.DraftDatabase.Draft; @@ -242,17 +241,12 @@ import java.util.Date; import java.util.LinkedList; import java.util.List; import java.util.Locale; -import java.util.Map; -import java.util.Set; import java.util.concurrent.ExecutionException; import java.util.concurrent.atomic.AtomicBoolean; import java.util.concurrent.atomic.AtomicInteger; import kotlin.Unit; import network.loki.messenger.R; -import nl.komponents.kovenant.Kovenant; -import nl.komponents.kovenant.KovenantApi; -import nl.komponents.kovenant.Promise; import static nl.komponents.kovenant.KovenantApi.task; import static org.thoughtcrime.securesms.TransportOption.Type; @@ -3032,16 +3026,18 @@ public class ConversationActivity extends PassphraseRequiredActionBarActivity long originalThreadID = lokiMessageDatabase.getOriginalThreadID(friendRequest.id); long threadId = originalThreadID < 0 ? this.threadId : originalThreadID; - String contactID = DatabaseFactory.getThreadDatabase(this).getRecipientForThreadId(threadId).getAddress().toString(); + Address contact = DatabaseFactory.getThreadDatabase(this).getRecipientForThreadId(threadId).getAddress(); + String contactPubKey = contact.toString(); Context context = this; AsyncTask.execute(() -> { try { - MessageSender.sendBackgroundMessageToAllDevices(this, contactID); + MessageSender.sendBackgroundMessageToAllDevices(this, contactPubKey); + MessageSender.syncContact(this, contact); DatabaseFactory.getLokiThreadDatabase(context).setFriendRequestStatus(threadId, LokiThreadFriendRequestStatus.FRIENDS); lokiMessageDatabase.setFriendRequestStatus(friendRequest.id, LokiMessageFriendRequestStatus.REQUEST_ACCEPTED); Util.runOnMain(this::updateInputPanel); } catch (Exception e) { - Log.d("Loki", "Failed to send background message to: " + contactID + "."); + Log.d("Loki", "Failed to send background message to: " + contactPubKey + "."); } }); } diff --git a/src/org/thoughtcrime/securesms/jobs/PushDecryptJob.java b/src/org/thoughtcrime/securesms/jobs/PushDecryptJob.java index 347314f910..071e46251d 100644 --- a/src/org/thoughtcrime/securesms/jobs/PushDecryptJob.java +++ b/src/org/thoughtcrime/securesms/jobs/PushDecryptJob.java @@ -99,7 +99,6 @@ import org.thoughtcrime.securesms.util.IdentityUtil; import org.thoughtcrime.securesms.util.MediaUtil; import org.thoughtcrime.securesms.util.TextSecurePreferences; import org.thoughtcrime.securesms.util.Util; -import org.thoughtcrime.securesms.util.concurrent.SettableFuture; import org.whispersystems.libsignal.state.PreKeyBundle; import org.whispersystems.libsignal.state.SignalProtocolStore; import org.whispersystems.libsignal.util.guava.Optional; @@ -147,7 +146,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 { @@ -1100,6 +1098,8 @@ public class PushDecryptJob extends BaseJob implements InjectableType { // If the thread's friend request status is not `FRIENDS`, but we're receiving a message, // it must be a friend request accepted message. Declining a friend request doesn't send a message. lokiThreadDatabase.setFriendRequestStatus(threadID, LokiThreadFriendRequestStatus.FRIENDS); + // Send out a contact sync message + MessageSender.syncContact(context, contactID.getAddress()); // Update the last message if needed LokiStorageAPI.shared.getPrimaryDevicePublicKey(pubKey).success(primaryDevice -> { Util.runOnMain(() -> { @@ -1145,6 +1145,8 @@ public class PushDecryptJob extends BaseJob implements InjectableType { FriendRequestHandler.updateLastFriendRequestMessage(context, primaryDeviceThreadID, LokiMessageFriendRequestStatus.REQUEST_ACCEPTED); // Accept the friend request MessageSender.sendBackgroundMessage(context, content.getSender()); + // Send contact sync message + MessageSender.syncContact(context, originalRecipient.getAddress()); } 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 diff --git a/src/org/thoughtcrime/securesms/loki/MultiDeviceUtilities.kt b/src/org/thoughtcrime/securesms/loki/MultiDeviceUtilities.kt index 580ade8175..7f3883e73c 100644 --- a/src/org/thoughtcrime/securesms/loki/MultiDeviceUtilities.kt +++ b/src/org/thoughtcrime/securesms/loki/MultiDeviceUtilities.kt @@ -2,7 +2,6 @@ package org.thoughtcrime.securesms.loki import android.content.Context -import android.os.Handler import nl.komponents.kovenant.* import nl.komponents.kovenant.functional.bind import nl.komponents.kovenant.functional.map @@ -10,7 +9,6 @@ import org.thoughtcrime.securesms.ApplicationContext import org.thoughtcrime.securesms.crypto.IdentityKeyUtil import org.thoughtcrime.securesms.database.Address import org.thoughtcrime.securesms.database.DatabaseFactory -import org.thoughtcrime.securesms.jobs.MultiDeviceContactUpdateJob import org.thoughtcrime.securesms.logging.Log import org.thoughtcrime.securesms.recipients.Recipient import org.thoughtcrime.securesms.sms.MessageSender @@ -130,7 +128,7 @@ fun signAndSendPairingAuthorisationMessage(context: Context, pairingAuthorisatio // If both promises complete successfully then we should sync our contacts all(listOf(sendPromise, updatePromise), cancelOthersOnError = false).success { Log.d("Loki", "Successfully pairing with a secondary device! Syncing contacts.") - MessageSender.sendContactSyncMessage(context) + MessageSender.syncAllContacts(context) } } diff --git a/src/org/thoughtcrime/securesms/sms/MessageSender.java b/src/org/thoughtcrime/securesms/sms/MessageSender.java index 3e9a62035a..4b4726f4df 100644 --- a/src/org/thoughtcrime/securesms/sms/MessageSender.java +++ b/src/org/thoughtcrime/securesms/sms/MessageSender.java @@ -18,6 +18,7 @@ package org.thoughtcrime.securesms.sms; import android.content.Context; import android.support.annotation.NonNull; +import android.support.annotation.Nullable; import org.thoughtcrime.securesms.ApplicationContext; import org.thoughtcrime.securesms.attachments.Attachment; @@ -66,7 +67,6 @@ import org.whispersystems.signalservice.loki.utilities.PromiseUtil; import java.io.IOException; import java.util.Map; -import java.util.Set; import kotlin.Unit; import nl.komponents.kovenant.Kovenant; @@ -78,12 +78,21 @@ public class MessageSender { private enum MessageType { TEXT, MEDIA } - public static void sendContactSyncMessage(Context context) { + public static void syncAllContacts(Context context) { ApplicationContext.getInstance(context).getJobManager().add(new MultiDeviceContactUpdateJob(context, true)); } - public static void sendContactSyncMessage(Context context, Address address) { - ApplicationContext.getInstance(context).getJobManager().add(new MultiDeviceContactUpdateJob(context, address)); + /** + * Send a contact sync message to all our devices telling them that we want to sync `contact` + */ + public static void syncContact(Context context, Address contact) { + // Don't bother sending a contact sync message if it's one of our devices that we want to sync across + MultiDeviceUtilities.isOneOfOurDevices(context, contact).success(isOneOfOurDevice -> { + if (!isOneOfOurDevice) { + ApplicationContext.getInstance(context).getJobManager().add(new MultiDeviceContactUpdateJob(context, contact)); + } + return Unit.INSTANCE; + }); } public static void sendBackgroundMessageToAllDevices(Context context, String contactHexEncodedPublicKey) { @@ -100,11 +109,10 @@ public class MessageSender { long threadID = DatabaseFactory.getThreadDatabase(context).getThreadIdIfExistsFor(recipient); if (threadID < 0) { continue; } LokiThreadFriendRequestStatus friendRequestStatus = DatabaseFactory.getLokiThreadDatabase(context).getFriendRequestStatus(threadID); + // TODO: Do we want to send a bg message regardless of FR status? OR do we want to send a custom FR to those we are not friends with 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; @@ -112,10 +120,15 @@ public class MessageSender { } public static void sendBackgroundMessage(Context context, String contactHexEncodedPublicKey) { + sendMessageWithBody(context, contactHexEncodedPublicKey, null); + } + + public static void sendMessageWithBody(Context context, String contactHexEncodedPublicKey, @Nullable String messageBody) { Util.runOnMain(() -> { SignalServiceMessageSender messageSender = ApplicationContext.getInstance(context).communicationModule.provideSignalMessageSender(); SignalServiceAddress address = new SignalServiceAddress(contactHexEncodedPublicKey); - SignalServiceDataMessage message = new SignalServiceDataMessage(System.currentTimeMillis(), null); + String body = (messageBody == null || messageBody.isEmpty()) ? null : messageBody; + SignalServiceDataMessage message = new SignalServiceDataMessage(System.currentTimeMillis(), body); try { // Try send to the original person messageSender.sendMessage(0, address, Optional.absent(), message); // The message ID doesn't matter