Sync groups upon linking device.

This commit is contained in:
Mikunj 2020-02-10 13:22:23 +11:00
parent f73f62ef59
commit 7f51baadd4
5 changed files with 48 additions and 12 deletions

View File

@ -206,14 +206,11 @@ public class GroupMessageProcessor {
@NonNull GroupRecord record) @NonNull GroupRecord record)
{ {
String hexEncodedPublicKey = getMasterHexEncodedPublicKey(context, content.getSender()); String hexEncodedPublicKey = getMasterHexEncodedPublicKey(context, content.getSender());
String ourPublicKey = getMasterHexEncodedPublicKey(context, TextSecurePreferences.getLocalNumber(context)); if (record.getMembers().contains(Address.fromSerialized(hexEncodedPublicKey))) {
// 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))) {
ApplicationContext.getInstance(context) ApplicationContext.getInstance(context)
.getJobManager() .getJobManager()
.add(new PushGroupUpdateJob(content.getSender(), group.getGroupId())); .add(new PushGroupUpdateJob(content.getSender(), group.getGroupId()));
} }
return null; return null;
} }

View File

@ -85,18 +85,23 @@ public class MultiDeviceGroupUpdateJob extends BaseJob implements InjectableType
reader = DatabaseFactory.getGroupDatabase(context).getGroups(); reader = DatabaseFactory.getGroupDatabase(context).getGroups();
while ((record = reader.getNext()) != null) { while ((record = reader.getNext()) != null) {
if (!record.isMms() && !record.isPublicChat() && !record.isRSSFeed()) { if (record.isSignalGroup()) {
List<String> members = new LinkedList<>(); List<String> members = new LinkedList<>();
List<String> admins = new LinkedList<>();
for (Address member : record.getMembers()) { for (Address member : record.getMembers()) {
members.add(member.serialize()); 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); Recipient recipient = Recipient.from(context, Address.fromSerialized(GroupUtil.getEncodedId(record.getId(), record.isMms())), false);
Optional<Integer> expirationTimer = recipient.getExpireMessages() > 0 ? Optional.of(recipient.getExpireMessages()) : Optional.absent(); Optional<Integer> expirationTimer = recipient.getExpireMessages() > 0 ? Optional.of(recipient.getExpireMessages()) : Optional.absent();
out.write(new DeviceGroup(record.getId(), Optional.fromNullable(record.getTitle()), out.write(new DeviceGroup(record.getId(), Optional.fromNullable(record.getTitle()),
members, getAvatar(record.getAvatar()), members, admins, getAvatar(record.getAvatar()),
record.isActive(), expirationTimer, record.isActive(), expirationTimer,
Optional.of(recipient.getColor().serialize()), Optional.of(recipient.getColor().serialize()),
recipient.isBlocked())); recipient.isBlocked()));
@ -120,8 +125,7 @@ public class MultiDeviceGroupUpdateJob extends BaseJob implements InjectableType
@Override @Override
public boolean onShouldRetry(@NonNull Exception exception) { public boolean onShouldRetry(@NonNull Exception exception) {
if (exception instanceof PushNetworkException) return true; return exception instanceof PushNetworkException;
return false;
} }
@Override @Override

View File

@ -107,6 +107,7 @@ import org.whispersystems.libsignal.state.PreKeyBundle;
import org.whispersystems.libsignal.state.SignalProtocolStore; import org.whispersystems.libsignal.state.SignalProtocolStore;
import org.whispersystems.libsignal.util.guava.Optional; import org.whispersystems.libsignal.util.guava.Optional;
import org.whispersystems.signalservice.api.SignalServiceMessageSender; 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.SignalServiceContent;
import org.whispersystems.signalservice.api.messages.SignalServiceDataMessage; import org.whispersystems.signalservice.api.messages.SignalServiceDataMessage;
import org.whispersystems.signalservice.api.messages.SignalServiceDataMessage.Preview; 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.ContactsMessage;
import org.whispersystems.signalservice.api.messages.multidevice.DeviceContact; import org.whispersystems.signalservice.api.messages.multidevice.DeviceContact;
import org.whispersystems.signalservice.api.messages.multidevice.DeviceContactsInputStream; 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.ReadMessage;
import org.whispersystems.signalservice.api.messages.multidevice.RequestMessage; import org.whispersystems.signalservice.api.messages.multidevice.RequestMessage;
import org.whispersystems.signalservice.api.messages.multidevice.SentTranscriptMessage; 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.getVerified().isPresent()) handleSynchronizeVerifiedMessage(syncMessage.getVerified().get());
else if (syncMessage.getStickerPackOperations().isPresent()) handleSynchronizeStickerPackOperation(syncMessage.getStickerPackOperations().get()); else if (syncMessage.getStickerPackOperations().isPresent()) handleSynchronizeStickerPackOperation(syncMessage.getStickerPackOperations().get());
else if (syncMessage.getContacts().isPresent()) handleContactSyncMessage(syncMessage.getContacts().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 Log.w(TAG, "Contains no known sync types...");
} else if (content.getCallMessage().isPresent()) { } else if (content.getCallMessage().isPresent()) {
Log.i(TAG, "Got call message..."); 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<DeviceGroup> 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, private void handleSynchronizeSentMessage(@NonNull SignalServiceContent content,
@NonNull SentTranscriptMessage message) @NonNull SentTranscriptMessage message)
throws StorageFailedException throws StorageFailedException

View File

@ -145,12 +145,12 @@ class LinkedDevicesActivity : PassphraseRequiredActionBarActivity, LoaderManager
override fun onDeviceLinkRequestAuthorized(deviceLink: DeviceLink) { override fun onDeviceLinkRequestAuthorized(deviceLink: DeviceLink) {
LokiFileServerAPI.shared.addDeviceLink(deviceLink).success { LokiFileServerAPI.shared.addDeviceLink(deviceLink).success {
signAndSendDeviceLinkMessage(this, deviceLink).success { signAndSendDeviceLinkMessage(this, deviceLink).successUi {
TextSecurePreferences.setMultiDevice(this, true)
Util.runOnMain {
LoaderManager.getInstance(this).restartLoader(0, null, this) LoaderManager.getInstance(this).restartLoader(0, null, this)
} }.success {
TextSecurePreferences.setMultiDevice(this, true)
Timer().schedule(4000) { Timer().schedule(4000) {
MessageSender.syncAllGroups(this@LinkedDevicesActivity)
MessageSender.syncAllContacts(this@LinkedDevicesActivity, Address.fromSerialized(deviceLink.slaveHexEncodedPublicKey)) MessageSender.syncAllContacts(this@LinkedDevicesActivity, Address.fromSerialized(deviceLink.slaveHexEncodedPublicKey))
} }
}.fail { }.fail {

View File

@ -37,6 +37,7 @@ import org.thoughtcrime.securesms.jobmanager.Job;
import org.thoughtcrime.securesms.jobmanager.JobManager; import org.thoughtcrime.securesms.jobmanager.JobManager;
import org.thoughtcrime.securesms.jobs.MmsSendJob; import org.thoughtcrime.securesms.jobs.MmsSendJob;
import org.thoughtcrime.securesms.jobs.MultiDeviceContactUpdateJob; import org.thoughtcrime.securesms.jobs.MultiDeviceContactUpdateJob;
import org.thoughtcrime.securesms.jobs.MultiDeviceGroupUpdateJob;
import org.thoughtcrime.securesms.jobs.PushGroupSendJob; import org.thoughtcrime.securesms.jobs.PushGroupSendJob;
import org.thoughtcrime.securesms.jobs.PushMediaSendJob; import org.thoughtcrime.securesms.jobs.PushMediaSendJob;
import org.thoughtcrime.securesms.jobs.PushTextSendJob; import org.thoughtcrime.securesms.jobs.PushTextSendJob;
@ -81,6 +82,10 @@ public class MessageSender {
ApplicationContext.getInstance(context).getJobManager().add(new MultiDeviceContactUpdateJob(context, recipient, true)); 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` * Send a contact sync message to all our devices telling them that we want to sync `contact`
*/ */