Refactor multi device message sending

pull/192/head
nielsandriesse 5 years ago
parent eb5b8886d4
commit d0742cf09f

@ -49,7 +49,7 @@ import org.thoughtcrime.securesms.database.Address;
import org.thoughtcrime.securesms.database.DatabaseFactory; import org.thoughtcrime.securesms.database.DatabaseFactory;
import org.thoughtcrime.securesms.database.MessagingDatabase.MarkedMessageInfo; import org.thoughtcrime.securesms.database.MessagingDatabase.MarkedMessageInfo;
import org.thoughtcrime.securesms.lock.RegistrationLockDialog; import org.thoughtcrime.securesms.lock.RegistrationLockDialog;
import org.thoughtcrime.securesms.loki.RecipientAvatarModifiedEvent; import org.thoughtcrime.securesms.loki.utilities.ProfilePictureModifiedEvent;
import org.thoughtcrime.securesms.loki.activities.JoinPublicChatActivity; import org.thoughtcrime.securesms.loki.activities.JoinPublicChatActivity;
import org.thoughtcrime.securesms.mms.GlideApp; import org.thoughtcrime.securesms.mms.GlideApp;
import org.thoughtcrime.securesms.notifications.MarkReadReceiver; import org.thoughtcrime.securesms.notifications.MarkReadReceiver;
@ -330,7 +330,7 @@ public class ConversationListActivity extends PassphraseRequiredActionBarActivit
} }
@Subscribe(threadMode = ThreadMode.MAIN) @Subscribe(threadMode = ThreadMode.MAIN)
public void onAvatarModified(RecipientAvatarModifiedEvent event) { public void onAvatarModified(ProfilePictureModifiedEvent event) {
Recipient recipient = event.getRecipient(); Recipient recipient = event.getRecipient();
if (recipient.isLocalNumber() || recipient.isUserMasterDevice()) { if (recipient.isLocalNumber() || recipient.isUserMasterDevice()) {
initializeProfileIcon(recipient); initializeProfileIcon(recipient);

@ -1,5 +0,0 @@
package org.thoughtcrime.securesms.loki
import org.thoughtcrime.securesms.recipients.Recipient
data class RecipientAvatarModifiedEvent(val recipient: Recipient)

@ -2,7 +2,7 @@ package org.thoughtcrime.securesms.loki.protocol
import org.whispersystems.signalservice.internal.util.JsonUtil import org.whispersystems.signalservice.internal.util.JsonUtil
data class EphemeralMessage private constructor(val data: Map<*, *>) { class EphemeralMessage private constructor(val data: Map<*, *>) {
companion object { companion object {

@ -19,6 +19,7 @@ import javax.inject.Inject
class MultiDeviceOpenGroupUpdateJob private constructor(parameters: Parameters) : BaseJob(parameters), InjectableType { class MultiDeviceOpenGroupUpdateJob private constructor(parameters: Parameters) : BaseJob(parameters), InjectableType {
companion object { companion object {
const val KEY = "MultiDeviceOpenGroupUpdateJob" const val KEY = "MultiDeviceOpenGroupUpdateJob"
} }

@ -2,7 +2,17 @@ package org.thoughtcrime.securesms.loki.protocol
import android.content.Context import android.content.Context
import org.thoughtcrime.securesms.ApplicationContext import org.thoughtcrime.securesms.ApplicationContext
import org.thoughtcrime.securesms.database.Address
import org.thoughtcrime.securesms.database.DatabaseFactory
import org.thoughtcrime.securesms.jobs.PushMediaSendJob
import org.thoughtcrime.securesms.jobs.PushSendJob
import org.thoughtcrime.securesms.jobs.PushTextSendJob
import org.thoughtcrime.securesms.recipients.Recipient import org.thoughtcrime.securesms.recipients.Recipient
import org.whispersystems.signalservice.loki.api.fileserver.LokiFileServerAPI
import org.whispersystems.signalservice.loki.protocol.meta.SessionMetaProtocol
import org.whispersystems.signalservice.loki.protocol.multidevice.MultiDeviceProtocol
import org.whispersystems.signalservice.loki.protocol.todo.LokiMessageFriendRequestStatus
import org.whispersystems.signalservice.loki.protocol.todo.LokiThreadFriendRequestStatus
object MultiDeviceProtocol { object MultiDeviceProtocol {
@ -12,6 +22,8 @@ object MultiDeviceProtocol {
ApplicationContext.getInstance(context).jobManager.add(PushEphemeralMessageSendJob(unlinkingRequest)) ApplicationContext.getInstance(context).jobManager.add(PushEphemeralMessageSendJob(unlinkingRequest))
} }
enum class MessageType { Text, Media }
@JvmStatic @JvmStatic
fun sendTextPush(context: Context, recipient: Recipient, messageID: Long) { fun sendTextPush(context: Context, recipient: Recipient, messageID: Long) {
@ -22,65 +34,61 @@ object MultiDeviceProtocol {
} }
// private static void sendMessagePush(Context context, MessageType type, Recipient recipient, long messageId) { private fun sendMessagePushToDevice(context: Context, recipient: Recipient, messageID: Long, messageType: MessageType): PushSendJob {
// JobManager jobManager = ApplicationContext.getInstance(context).getJobManager(); val threadID = DatabaseFactory.getThreadDatabase(context).getThreadIdFor(recipient)
// val threadFRStatus = DatabaseFactory.getLokiThreadDatabase(context).getFriendRequestStatus(threadID)
// // Just send the message normally if it's a group message or we're sending to one of our devices val isContactFriend = (threadFRStatus == LokiThreadFriendRequestStatus.FRIENDS)
// String recipientHexEncodedPublicKey = recipient.getAddress().serialize(); val messageFRStatus = DatabaseFactory.getLokiMessageDatabase(context).getFriendRequestStatus(messageID)
// if (GeneralUtilitiesKt.isPublicChat(context, recipientHexEncodedPublicKey) || PromiseUtil.get(MultiDeviceUtilities.isOneOfOurDevices(context, recipient.getAddress()), false)) { val isFRMessage = (messageFRStatus != LokiMessageFriendRequestStatus.NONE)
// if (type == MessageType.MEDIA) { val hasVisibleContent = when (messageType) {
// PushMediaSendJob.enqueue(context, jobManager, messageId, recipient.getAddress(), false); MessageType.Text -> DatabaseFactory.getSmsDatabase(context).getMessage(messageID).body.isNotBlank()
// } else { MessageType.Media -> {
// jobManager.add(new PushTextSendJob(messageId, recipient.getAddress())); val outgoingMediaMessage = DatabaseFactory.getMmsDatabase(context).getOutgoingMessage(messageID)
// } outgoingMediaMessage.body.isNotBlank() || outgoingMediaMessage.attachments.isNotEmpty()
// return; }
// } }
// val shouldSendAutoGeneratedFR = !isContactFriend && !isFRMessage
// // If we get here then we are sending a message to a device that is not ours && !SessionMetaProtocol.shared.isNoteToSelf(recipient.address.serialize()) && !recipient.address.isGroup // Group threads work through session requests
// boolean[] hasSentSyncMessage = { false }; && hasVisibleContent
// MultiDeviceUtilities.getAllDevicePublicKeysWithFriendStatus(context, recipientHexEncodedPublicKey).success(devices -> { if (!shouldSendAutoGeneratedFR) {
// int friendCount = MultiDeviceUtilities.getFriendCount(context, devices.keySet()); when (messageType) {
// Util.runOnMain(() -> { MessageType.Text -> return PushTextSendJob(messageID, recipient.address)
// ArrayList<Job> jobs = new ArrayList<>(); MessageType.Media -> return PushMediaSendJob(messageID, recipient.address)
// for (Map.Entry<String, Boolean> entry : devices.entrySet()) { }
// String deviceHexEncodedPublicKey = entry.getKey(); } else {
// boolean isFriend = entry.getValue(); val autoGeneratedFRMessage = "Please accept to enable messages to be synced across devices"
// when (messageType) {
// Address address = Address.fromSerialized(deviceHexEncodedPublicKey); MessageType.Text -> return PushTextSendJob(messageID, messageID, recipient.address, true, autoGeneratedFRMessage)
// long messageIDToUse = recipientHexEncodedPublicKey.equals(deviceHexEncodedPublicKey) ? messageId : -1L; MessageType.Media -> return PushMediaSendJob(messageID, messageID, recipient.address, true, autoGeneratedFRMessage)
// }
// if (isFriend) { }
// // Send a normal message if the user is friends with the recipient }
// // We should also send a sync message if we haven't already sent one
// boolean shouldSendSyncMessage = !hasSentSyncMessage[0] && address.isPhone(); private fun sendMessagePush(context: Context, recipient: Recipient, messageID: Long, messageType: MessageType) {
// if (type == MessageType.MEDIA) { val jobManager = ApplicationContext.getInstance(context).jobManager
// jobs.add(new PushMediaSendJob(messageId, messageIDToUse, address, false, null, shouldSendSyncMessage)); val isMultiDeviceRequired = !recipient.address.isOpenGroup
// } else { if (!isMultiDeviceRequired) {
// jobs.add(new PushTextSendJob(messageId, messageIDToUse, address, shouldSendSyncMessage)); when (messageType) {
// } MessageType.Text -> jobManager.add(PushTextSendJob(messageID, recipient.address))
// if (shouldSendSyncMessage) { hasSentSyncMessage[0] = true; } MessageType.Media -> PushMediaSendJob.enqueue(context, jobManager, messageID, recipient.address)
// } else { }
// // Send friend requests to non-friends. If the user is friends with any }
// // of the devices then send out a default friend request message. val publicKey = recipient.address.serialize()
// boolean isFriendsWithAny = (friendCount > 0); LokiFileServerAPI.shared.getDeviceLinks(publicKey).success {
// String defaultFriendRequestMessage = isFriendsWithAny ? "Please accept to enable messages to be synced across devices" : null; val devices = MultiDeviceProtocol.shared.getAllLinkedDevices(publicKey)
// if (type == MessageType.MEDIA) { val jobs = devices.map { sendMessagePushToDevice(context, Recipient.from(context, Address.fromSerialized(it), false), messageID, messageType) }
// jobs.add(new PushMediaSendJob(messageId, messageIDToUse, address, true, defaultFriendRequestMessage, false)); @Suppress("UNCHECKED_CAST")
// } else { when (messageType) {
// jobs.add(new PushTextSendJob(messageId, messageIDToUse, address, true, defaultFriendRequestMessage, false)); MessageType.Text -> jobManager.startChain(jobs).enqueue()
// } MessageType.Media -> PushMediaSendJob.enqueue(context, jobManager, jobs as List<PushMediaSendJob>)
// } }
// } }.fail { exception ->
// // Proceed even if updating the recipient's device links failed, so that message sending
// // Start the send // is independent of whether the file server is online
// if (type == MessageType.MEDIA) { when (messageType) {
// PushMediaSendJob.enqueue(context, jobManager, (List<PushMediaSendJob>)(List)jobs); MessageType.Text -> jobManager.add(PushTextSendJob(messageID, recipient.address))
// } else { MessageType.Media -> PushMediaSendJob.enqueue(context, jobManager, messageID, recipient.address)
// // Schedule text send jobs }
// jobManager.startChain(jobs).enqueue(); }
// } }
// });
// return Unit.INSTANCE;
// });
// }
} }

@ -15,16 +15,12 @@ import org.whispersystems.signalservice.api.push.SignalServiceAddress
import java.io.IOException import java.io.IOException
import java.util.concurrent.TimeUnit import java.util.concurrent.TimeUnit
class PushEphemeralMessageSendJob private constructor( class PushEphemeralMessageSendJob private constructor(parameters: Parameters, private val message: EphemeralMessage) : BaseJob(parameters) {
parameters: Parameters,
private val message: EphemeralMessage
) : BaseJob(parameters) {
companion object { companion object {
private val KEY_MESSAGE = "message"
const val KEY = "PushBackgroundMessageSendJob" const val KEY = "PushBackgroundMessageSendJob"
private val KEY_MESSAGE = "message"
} }
constructor(message: EphemeralMessage) : this(Parameters.Builder() constructor(message: EphemeralMessage) : this(Parameters.Builder()

@ -40,6 +40,7 @@ object SyncMessagesProtocol {
fun shouldSyncContact(context: Context, address: Address): Boolean { fun shouldSyncContact(context: Context, address: Address): Boolean {
if (!PublicKeyValidation.isValid(address.serialize())) { return false } if (!PublicKeyValidation.isValid(address.serialize())) { return false }
if (address.serialize() == TextSecurePreferences.getMasterHexEncodedPublicKey(context)) { return false } if (address.serialize() == TextSecurePreferences.getMasterHexEncodedPublicKey(context)) { return false }
if (address.serialize() == TextSecurePreferences.getLocalNumber(context)) { return false }
val threadID = DatabaseFactory.getThreadDatabase(context).getThreadIdFor(Recipient.from(context, address, false)) val threadID = DatabaseFactory.getThreadDatabase(context).getThreadIdFor(Recipient.from(context, address, false))
val isFriend = DatabaseFactory.getLokiThreadDatabase(context).getFriendRequestStatus(threadID) == LokiThreadFriendRequestStatus.FRIENDS val isFriend = DatabaseFactory.getLokiThreadDatabase(context).getFriendRequestStatus(threadID) == LokiThreadFriendRequestStatus.FRIENDS
return isFriend return isFriend

@ -0,0 +1,5 @@
package org.thoughtcrime.securesms.loki.utilities
import org.thoughtcrime.securesms.recipients.Recipient
data class ProfilePictureModifiedEvent(val recipient: Recipient)

@ -44,7 +44,7 @@ import org.thoughtcrime.securesms.database.RecipientDatabase.UnidentifiedAccessM
import org.thoughtcrime.securesms.database.RecipientDatabase.VibrateState; import org.thoughtcrime.securesms.database.RecipientDatabase.VibrateState;
import org.thoughtcrime.securesms.logging.Log; import org.thoughtcrime.securesms.logging.Log;
import org.thoughtcrime.securesms.loki.todo.JazzIdenticonContactPhoto; import org.thoughtcrime.securesms.loki.todo.JazzIdenticonContactPhoto;
import org.thoughtcrime.securesms.loki.RecipientAvatarModifiedEvent; import org.thoughtcrime.securesms.loki.utilities.ProfilePictureModifiedEvent;
import org.thoughtcrime.securesms.notifications.NotificationChannels; import org.thoughtcrime.securesms.notifications.NotificationChannels;
import org.thoughtcrime.securesms.recipients.RecipientProvider.RecipientDetails; import org.thoughtcrime.securesms.recipients.RecipientProvider.RecipientDetails;
import org.thoughtcrime.securesms.util.FutureTaskListener; import org.thoughtcrime.securesms.util.FutureTaskListener;
@ -399,7 +399,7 @@ public class Recipient implements RecipientModifiedListener {
} }
notifyListeners(); notifyListeners();
EventBus.getDefault().post(new RecipientAvatarModifiedEvent(this)); EventBus.getDefault().post(new ProfilePictureModifiedEvent(this));
} }
public synchronized boolean isProfileSharing() { public synchronized boolean isProfileSharing() {

Loading…
Cancel
Save