From 7f51baadd458ca8b6edf3f2d8fd6a9d72d306c1c Mon Sep 17 00:00:00 2001 From: Mikunj Date: Mon, 10 Feb 2020 13:22:23 +1100 Subject: [PATCH] Sync groups upon linking device. --- .../groups/GroupMessageProcessor.java | 5 +--- .../jobs/MultiDeviceGroupUpdateJob.java | 12 +++++--- .../securesms/jobs/PushDecryptJob.java | 30 +++++++++++++++++++ .../activities/LinkedDevicesActivity.kt | 8 ++--- .../securesms/sms/MessageSender.java | 5 ++++ 5 files changed, 48 insertions(+), 12 deletions(-) diff --git a/src/org/thoughtcrime/securesms/groups/GroupMessageProcessor.java b/src/org/thoughtcrime/securesms/groups/GroupMessageProcessor.java index d1f37ce390..c9145e77e1 100644 --- a/src/org/thoughtcrime/securesms/groups/GroupMessageProcessor.java +++ b/src/org/thoughtcrime/securesms/groups/GroupMessageProcessor.java @@ -206,14 +206,11 @@ public class GroupMessageProcessor { @NonNull GroupRecord record) { String hexEncodedPublicKey = getMasterHexEncodedPublicKey(context, content.getSender()); - String ourPublicKey = getMasterHexEncodedPublicKey(context, TextSecurePreferences.getLocalNumber(context)); - // If the requester is a group member and we are admin then we should send them the group update - if (record.getMembers().contains(Address.fromSerialized(hexEncodedPublicKey)) && record.getAdmins().contains(Address.fromSerialized(ourPublicKey))) { + if (record.getMembers().contains(Address.fromSerialized(hexEncodedPublicKey))) { ApplicationContext.getInstance(context) .getJobManager() .add(new PushGroupUpdateJob(content.getSender(), group.getGroupId())); } - return null; } diff --git a/src/org/thoughtcrime/securesms/jobs/MultiDeviceGroupUpdateJob.java b/src/org/thoughtcrime/securesms/jobs/MultiDeviceGroupUpdateJob.java index 52a81d5d57..9ef69669ea 100644 --- a/src/org/thoughtcrime/securesms/jobs/MultiDeviceGroupUpdateJob.java +++ b/src/org/thoughtcrime/securesms/jobs/MultiDeviceGroupUpdateJob.java @@ -85,18 +85,23 @@ public class MultiDeviceGroupUpdateJob extends BaseJob implements InjectableType reader = DatabaseFactory.getGroupDatabase(context).getGroups(); while ((record = reader.getNext()) != null) { - if (!record.isMms() && !record.isPublicChat() && !record.isRSSFeed()) { + if (record.isSignalGroup()) { List members = new LinkedList<>(); + List admins = new LinkedList<>(); for (Address member : record.getMembers()) { members.add(member.serialize()); } + for (Address admin : record.getAdmins()) { + admins.add(admin.serialize()); + } + Recipient recipient = Recipient.from(context, Address.fromSerialized(GroupUtil.getEncodedId(record.getId(), record.isMms())), false); Optional expirationTimer = recipient.getExpireMessages() > 0 ? Optional.of(recipient.getExpireMessages()) : Optional.absent(); out.write(new DeviceGroup(record.getId(), Optional.fromNullable(record.getTitle()), - members, getAvatar(record.getAvatar()), + members, admins, getAvatar(record.getAvatar()), record.isActive(), expirationTimer, Optional.of(recipient.getColor().serialize()), recipient.isBlocked())); @@ -120,8 +125,7 @@ public class MultiDeviceGroupUpdateJob extends BaseJob implements InjectableType @Override public boolean onShouldRetry(@NonNull Exception exception) { - if (exception instanceof PushNetworkException) return true; - return false; + return exception instanceof PushNetworkException; } @Override diff --git a/src/org/thoughtcrime/securesms/jobs/PushDecryptJob.java b/src/org/thoughtcrime/securesms/jobs/PushDecryptJob.java index 49163e4f2f..6da22c439c 100644 --- a/src/org/thoughtcrime/securesms/jobs/PushDecryptJob.java +++ b/src/org/thoughtcrime/securesms/jobs/PushDecryptJob.java @@ -107,6 +107,7 @@ import org.whispersystems.libsignal.state.PreKeyBundle; import org.whispersystems.libsignal.state.SignalProtocolStore; import org.whispersystems.libsignal.util.guava.Optional; import org.whispersystems.signalservice.api.SignalServiceMessageSender; +import org.whispersystems.signalservice.api.messages.SignalServiceAttachment; import org.whispersystems.signalservice.api.messages.SignalServiceContent; import org.whispersystems.signalservice.api.messages.SignalServiceDataMessage; import org.whispersystems.signalservice.api.messages.SignalServiceDataMessage.Preview; @@ -123,6 +124,8 @@ import org.whispersystems.signalservice.api.messages.calls.SignalServiceCallMess import org.whispersystems.signalservice.api.messages.multidevice.ContactsMessage; import org.whispersystems.signalservice.api.messages.multidevice.DeviceContact; import org.whispersystems.signalservice.api.messages.multidevice.DeviceContactsInputStream; +import org.whispersystems.signalservice.api.messages.multidevice.DeviceGroup; +import org.whispersystems.signalservice.api.messages.multidevice.DeviceGroupsInputStream; import org.whispersystems.signalservice.api.messages.multidevice.ReadMessage; import org.whispersystems.signalservice.api.messages.multidevice.RequestMessage; import org.whispersystems.signalservice.api.messages.multidevice.SentTranscriptMessage; @@ -389,6 +392,7 @@ public class PushDecryptJob extends BaseJob implements InjectableType { else if (syncMessage.getVerified().isPresent()) handleSynchronizeVerifiedMessage(syncMessage.getVerified().get()); else if (syncMessage.getStickerPackOperations().isPresent()) handleSynchronizeStickerPackOperation(syncMessage.getStickerPackOperations().get()); else if (syncMessage.getContacts().isPresent()) handleContactSyncMessage(syncMessage.getContacts().get()); + else if (syncMessage.getGroups().isPresent()) handleGroupSyncMessage(content, syncMessage.getGroups().get()); else Log.w(TAG, "Contains no known sync types..."); } else if (content.getCallMessage().isPresent()) { Log.i(TAG, "Got call message..."); @@ -719,6 +723,32 @@ public class PushDecryptJob extends BaseJob implements InjectableType { } } + private void handleGroupSyncMessage(@NonNull SignalServiceContent content, @NonNull SignalServiceAttachment groupMessage) { + if (groupMessage.isStream()) { + Log.d("Loki", "Received group sync message"); + try { + InputStream in = groupMessage.asStream().getInputStream(); + DeviceGroupsInputStream groupsInputStream = new DeviceGroupsInputStream(in); + List groups = groupsInputStream.readAll(); + for (DeviceGroup group : groups) { + SignalServiceGroup serviceGroup = new SignalServiceGroup( + SignalServiceGroup.Type.UPDATE, + group.getId(), + SignalServiceGroup.GroupType.SIGNAL, + group.getName().orNull(), + group.getMembers(), + group.getAvatar().orNull(), + group.getAdmins() + ); + SignalServiceDataMessage dataMessage = new SignalServiceDataMessage(content.getTimestamp(), serviceGroup, null, null); + GroupMessageProcessor.process(context, content, dataMessage, false); + } + } catch (Exception e) { + Log.d("Loki", "Failed to sync group: " + e); + } + } + } + private void handleSynchronizeSentMessage(@NonNull SignalServiceContent content, @NonNull SentTranscriptMessage message) throws StorageFailedException diff --git a/src/org/thoughtcrime/securesms/loki/redesign/activities/LinkedDevicesActivity.kt b/src/org/thoughtcrime/securesms/loki/redesign/activities/LinkedDevicesActivity.kt index 94b4c09c9a..4061a03177 100644 --- a/src/org/thoughtcrime/securesms/loki/redesign/activities/LinkedDevicesActivity.kt +++ b/src/org/thoughtcrime/securesms/loki/redesign/activities/LinkedDevicesActivity.kt @@ -145,12 +145,12 @@ class LinkedDevicesActivity : PassphraseRequiredActionBarActivity, LoaderManager override fun onDeviceLinkRequestAuthorized(deviceLink: DeviceLink) { LokiFileServerAPI.shared.addDeviceLink(deviceLink).success { - signAndSendDeviceLinkMessage(this, deviceLink).success { + signAndSendDeviceLinkMessage(this, deviceLink).successUi { + LoaderManager.getInstance(this).restartLoader(0, null, this) + }.success { TextSecurePreferences.setMultiDevice(this, true) - Util.runOnMain { - LoaderManager.getInstance(this).restartLoader(0, null, this) - } Timer().schedule(4000) { + MessageSender.syncAllGroups(this@LinkedDevicesActivity) MessageSender.syncAllContacts(this@LinkedDevicesActivity, Address.fromSerialized(deviceLink.slaveHexEncodedPublicKey)) } }.fail { diff --git a/src/org/thoughtcrime/securesms/sms/MessageSender.java b/src/org/thoughtcrime/securesms/sms/MessageSender.java index 16e7a06842..80a4baa482 100644 --- a/src/org/thoughtcrime/securesms/sms/MessageSender.java +++ b/src/org/thoughtcrime/securesms/sms/MessageSender.java @@ -37,6 +37,7 @@ import org.thoughtcrime.securesms.jobmanager.Job; import org.thoughtcrime.securesms.jobmanager.JobManager; import org.thoughtcrime.securesms.jobs.MmsSendJob; import org.thoughtcrime.securesms.jobs.MultiDeviceContactUpdateJob; +import org.thoughtcrime.securesms.jobs.MultiDeviceGroupUpdateJob; import org.thoughtcrime.securesms.jobs.PushGroupSendJob; import org.thoughtcrime.securesms.jobs.PushMediaSendJob; import org.thoughtcrime.securesms.jobs.PushTextSendJob; @@ -81,6 +82,10 @@ public class MessageSender { ApplicationContext.getInstance(context).getJobManager().add(new MultiDeviceContactUpdateJob(context, recipient, true)); } + public static void syncAllGroups(Context context) { + ApplicationContext.getInstance(context).getJobManager().add(new MultiDeviceGroupUpdateJob()); + } + /** * Send a contact sync message to all our devices telling them that we want to sync `contact` */