mirror of
https://github.com/oxen-io/session-android.git
synced 2025-02-26 01:17:21 +00:00
Sync all contacts with only a specific device.
This may fix the issue where the sync message sending queue gets blocked because of sending full contact syncs to all devices.
This commit is contained in:
parent
aea686c856
commit
12639b491f
@ -37,6 +37,7 @@ import org.whispersystems.signalservice.api.messages.multidevice.DeviceContact;
|
|||||||
import org.whispersystems.signalservice.api.messages.multidevice.DeviceContactsOutputStream;
|
import org.whispersystems.signalservice.api.messages.multidevice.DeviceContactsOutputStream;
|
||||||
import org.whispersystems.signalservice.api.messages.multidevice.SignalServiceSyncMessage;
|
import org.whispersystems.signalservice.api.messages.multidevice.SignalServiceSyncMessage;
|
||||||
import org.whispersystems.signalservice.api.messages.multidevice.VerifiedMessage;
|
import org.whispersystems.signalservice.api.messages.multidevice.VerifiedMessage;
|
||||||
|
import org.whispersystems.signalservice.api.push.SignalServiceAddress;
|
||||||
import org.whispersystems.signalservice.api.push.exceptions.PushNetworkException;
|
import org.whispersystems.signalservice.api.push.exceptions.PushNetworkException;
|
||||||
import org.whispersystems.signalservice.api.util.InvalidNumberException;
|
import org.whispersystems.signalservice.api.util.InvalidNumberException;
|
||||||
import org.whispersystems.signalservice.loki.messaging.LokiThreadFriendRequestStatus;
|
import org.whispersystems.signalservice.loki.messaging.LokiThreadFriendRequestStatus;
|
||||||
@ -62,41 +63,57 @@ public class MultiDeviceContactUpdateJob extends BaseJob implements InjectableTy
|
|||||||
private static final long FULL_SYNC_TIME = TimeUnit.HOURS.toMillis(6);
|
private static final long FULL_SYNC_TIME = TimeUnit.HOURS.toMillis(6);
|
||||||
|
|
||||||
private static final String KEY_ADDRESS = "address";
|
private static final String KEY_ADDRESS = "address";
|
||||||
|
private static final String KEY_RECIPIENT = "recipient";
|
||||||
private static final String KEY_FORCE_SYNC = "force_sync";
|
private static final String KEY_FORCE_SYNC = "force_sync";
|
||||||
|
|
||||||
@Inject SignalServiceMessageSender messageSender;
|
@Inject SignalServiceMessageSender messageSender;
|
||||||
|
|
||||||
private @Nullable String address;
|
private @Nullable String address;
|
||||||
|
|
||||||
|
// The recipient of this sync message. If null then we send to all devices
|
||||||
|
private @Nullable String recipient;
|
||||||
|
|
||||||
private boolean forceSync;
|
private boolean forceSync;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a full contact sync job which syncs across to all other devices
|
||||||
|
*/
|
||||||
public MultiDeviceContactUpdateJob(@NonNull Context context) {
|
public MultiDeviceContactUpdateJob(@NonNull Context context) {
|
||||||
this(context, false);
|
this(context, false);
|
||||||
}
|
}
|
||||||
|
public MultiDeviceContactUpdateJob(@NonNull Context context, boolean forceSync) { this(context, null, forceSync); }
|
||||||
|
|
||||||
public MultiDeviceContactUpdateJob(@NonNull Context context, boolean forceSync) {
|
/**
|
||||||
this(context, null, forceSync);
|
* Create a full contact sync job which only gets sent to `recipient`
|
||||||
|
*/
|
||||||
|
public MultiDeviceContactUpdateJob(@NonNull Context context, @Nullable Address recipient, boolean forceSync) {
|
||||||
|
this(context, recipient, null, forceSync);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a single contact sync job which syncs across `address` to the all other devices
|
||||||
|
*/
|
||||||
public MultiDeviceContactUpdateJob(@NonNull Context context, @Nullable Address address) {
|
public MultiDeviceContactUpdateJob(@NonNull Context context, @Nullable Address address) {
|
||||||
this(context, address, true);
|
this(context, null, address, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
public MultiDeviceContactUpdateJob(@NonNull Context context, @Nullable Address address, boolean forceSync) {
|
private MultiDeviceContactUpdateJob(@NonNull Context context, @Nullable Address recipient, @Nullable Address address, boolean forceSync) {
|
||||||
this(new Job.Parameters.Builder()
|
this(new Job.Parameters.Builder()
|
||||||
.addConstraint(NetworkConstraint.KEY)
|
.addConstraint(NetworkConstraint.KEY)
|
||||||
.setQueue("MultiDeviceContactUpdateJob")
|
.setQueue("MultiDeviceContactUpdateJob")
|
||||||
.setLifespan(TimeUnit.DAYS.toMillis(1))
|
.setLifespan(TimeUnit.DAYS.toMillis(1))
|
||||||
.setMaxAttempts(3)
|
.setMaxAttempts(1)
|
||||||
.build(),
|
.build(),
|
||||||
|
recipient,
|
||||||
address,
|
address,
|
||||||
forceSync);
|
forceSync);
|
||||||
}
|
}
|
||||||
|
|
||||||
private MultiDeviceContactUpdateJob(@NonNull Job.Parameters parameters, @Nullable Address address, boolean forceSync) {
|
private MultiDeviceContactUpdateJob(@NonNull Job.Parameters parameters, @Nullable Address recipient, @Nullable Address address, boolean forceSync) {
|
||||||
super(parameters);
|
super(parameters);
|
||||||
|
|
||||||
this.forceSync = forceSync;
|
this.forceSync = forceSync;
|
||||||
|
this.recipient = (recipient != null) ? recipient.serialize() : null;
|
||||||
|
|
||||||
if (address != null) this.address = address.serialize();
|
if (address != null) this.address = address.serialize();
|
||||||
else this.address = null;
|
else this.address = null;
|
||||||
@ -106,6 +123,7 @@ public class MultiDeviceContactUpdateJob extends BaseJob implements InjectableTy
|
|||||||
public @NonNull Data serialize() {
|
public @NonNull Data serialize() {
|
||||||
return new Data.Builder().putString(KEY_ADDRESS, address)
|
return new Data.Builder().putString(KEY_ADDRESS, address)
|
||||||
.putBoolean(KEY_FORCE_SYNC, forceSync)
|
.putBoolean(KEY_FORCE_SYNC, forceSync)
|
||||||
|
.putString(KEY_RECIPIENT, recipient)
|
||||||
.build();
|
.build();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -124,7 +142,7 @@ public class MultiDeviceContactUpdateJob extends BaseJob implements InjectableTy
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (address == null) generateFullContactUpdate();
|
if (address == null) generateFullContactUpdate();
|
||||||
else generateSingleContactUpdate(Address.fromSerialized(address));
|
else if (address != TextSecurePreferences.getMasterHexEncodedPublicKey(context)) generateSingleContactUpdate(Address.fromSerialized(address));
|
||||||
}
|
}
|
||||||
|
|
||||||
private void generateSingleContactUpdate(@NonNull Address address)
|
private void generateSingleContactUpdate(@NonNull Address address)
|
||||||
@ -245,7 +263,8 @@ public class MultiDeviceContactUpdateJob extends BaseJob implements InjectableTy
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean onShouldRetry(@NonNull Exception exception) {
|
public boolean onShouldRetry(@NonNull Exception exception) {
|
||||||
if (exception instanceof PushNetworkException) return true;
|
// Loki - Disabled because we have our own retrying
|
||||||
|
// if (exception instanceof PushNetworkException) return true;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -265,9 +284,10 @@ public class MultiDeviceContactUpdateJob extends BaseJob implements InjectableTy
|
|||||||
.withLength(contactsFile.length())
|
.withLength(contactsFile.length())
|
||||||
.build();
|
.build();
|
||||||
|
|
||||||
|
SignalServiceAddress messageRecipient = recipient != null ? new SignalServiceAddress(recipient) : null;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
messageSender.sendMessage(0, SignalServiceSyncMessage.forContacts(new ContactsMessage(attachmentStream, complete)),
|
messageSender.sendMessage(0, SignalServiceSyncMessage.forContacts(new ContactsMessage(attachmentStream, complete)), messageRecipient);
|
||||||
UnidentifiedAccessUtil.getAccessForSync(context));
|
|
||||||
} catch (IOException ioe) {
|
} catch (IOException ioe) {
|
||||||
throw new NetworkException(ioe);
|
throw new NetworkException(ioe);
|
||||||
}
|
}
|
||||||
@ -375,7 +395,10 @@ public class MultiDeviceContactUpdateJob extends BaseJob implements InjectableTy
|
|||||||
String serialized = data.getString(KEY_ADDRESS);
|
String serialized = data.getString(KEY_ADDRESS);
|
||||||
Address address = serialized != null ? Address.fromSerialized(serialized) : null;
|
Address address = serialized != null ? Address.fromSerialized(serialized) : null;
|
||||||
|
|
||||||
return new MultiDeviceContactUpdateJob(parameters, address, data.getBoolean(KEY_FORCE_SYNC));
|
String recipientSerialized = data.getString(KEY_RECIPIENT);
|
||||||
|
Address recipient = recipientSerialized != null ? Address.fromSerialized(recipientSerialized) : null;
|
||||||
|
|
||||||
|
return new MultiDeviceContactUpdateJob(parameters, recipient, address, data.getBoolean(KEY_FORCE_SYNC));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -648,6 +648,7 @@ public class PushDecryptJob extends BaseJob implements InjectableType {
|
|||||||
|
|
||||||
private void handleSynchronizeContactMessage(@NonNull ContactsMessage contactsMessage) {
|
private void handleSynchronizeContactMessage(@NonNull ContactsMessage contactsMessage) {
|
||||||
if (contactsMessage.getContactsStream().isStream()) {
|
if (contactsMessage.getContactsStream().isStream()) {
|
||||||
|
Log.d("Loki", "Received contact sync message");
|
||||||
try {
|
try {
|
||||||
DeviceContactsInputStream contactsInputStream = new DeviceContactsInputStream(contactsMessage.getContactsStream().asStream().getInputStream());
|
DeviceContactsInputStream contactsInputStream = new DeviceContactsInputStream(contactsMessage.getContactsStream().asStream().getInputStream());
|
||||||
DeviceContact deviceContact = contactsInputStream.read();
|
DeviceContact deviceContact = contactsInputStream.read();
|
||||||
@ -665,9 +666,11 @@ public class PushDecryptJob extends BaseJob implements InjectableType {
|
|||||||
LokiThreadFriendRequestStatus status = DatabaseFactory.getLokiThreadDatabase(context).getFriendRequestStatus(threadId);
|
LokiThreadFriendRequestStatus status = DatabaseFactory.getLokiThreadDatabase(context).getFriendRequestStatus(threadId);
|
||||||
if (status == LokiThreadFriendRequestStatus.NONE || status == LokiThreadFriendRequestStatus.REQUEST_EXPIRED) {
|
if (status == LokiThreadFriendRequestStatus.NONE || status == LokiThreadFriendRequestStatus.REQUEST_EXPIRED) {
|
||||||
MessageSender.sendBackgroundFriendRequest(context, deviceContact.getNumber(), "This is an automated friend request. Still under testing!");
|
MessageSender.sendBackgroundFriendRequest(context, deviceContact.getNumber(), "This is an automated friend request. Still under testing!");
|
||||||
|
Log.d("Loki", "Sent friend request to " + deviceContact.getNumber());
|
||||||
} else if (status == LokiThreadFriendRequestStatus.REQUEST_RECEIVED) {
|
} else if (status == LokiThreadFriendRequestStatus.REQUEST_RECEIVED) {
|
||||||
// Accept the incoming friend request
|
// Accept the incoming friend request
|
||||||
becomeFriendsWithContact(deviceContact.getNumber(), false);
|
becomeFriendsWithContact(deviceContact.getNumber(), false);
|
||||||
|
Log.d("Loki", "Became friends with " + deviceContact.getNumber());
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: Handle blocked - If user is not blocked then we should do the friend request logic otherwise add them to our block list
|
// TODO: Handle blocked - If user is not blocked then we should do the friend request logic otherwise add them to our block list
|
||||||
@ -679,6 +682,7 @@ public class PushDecryptJob extends BaseJob implements InjectableType {
|
|||||||
}
|
}
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
// Exception is thrown when we don't have any more contacts to read from
|
// Exception is thrown when we don't have any more contacts to read from
|
||||||
|
return;
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
Log.d("Loki", "Failed to sync contact: " + e.getMessage());
|
Log.d("Loki", "Failed to sync contact: " + e.getMessage());
|
||||||
}
|
}
|
||||||
@ -1113,6 +1117,11 @@ public class PushDecryptJob extends BaseJob implements InjectableType {
|
|||||||
if (content.senderDisplayName.isPresent() && content.senderDisplayName.get().length() > 0) {
|
if (content.senderDisplayName.isPresent() && content.senderDisplayName.get().length() > 0) {
|
||||||
setDisplayName(envelope.getSource(), content.senderDisplayName.get());
|
setDisplayName(envelope.getSource(), content.senderDisplayName.get());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Contact sync
|
||||||
|
if (content.getSyncMessage().isPresent() && content.getSyncMessage().get().getContacts().isPresent()) {
|
||||||
|
handleSynchronizeContactMessage(content.getSyncMessage().get().getContacts().get());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void setDisplayName(String hexEncodedPublicKey, String profileName) {
|
private void setDisplayName(String hexEncodedPublicKey, String profileName) {
|
||||||
|
@ -123,10 +123,12 @@ fun signAndSendPairingAuthorisationMessage(context: Context, pairingAuthorisatio
|
|||||||
DatabaseFactory.getLokiAPIDatabase(context).insertOrUpdatePairingAuthorisation(signedPairingAuthorisation)
|
DatabaseFactory.getLokiAPIDatabase(context).insertOrUpdatePairingAuthorisation(signedPairingAuthorisation)
|
||||||
TextSecurePreferences.setMultiDevice(context, true)
|
TextSecurePreferences.setMultiDevice(context, true)
|
||||||
|
|
||||||
|
val address = Address.fromSerialized(pairingAuthorisation.secondaryDevicePublicKey);
|
||||||
|
|
||||||
val sendPromise = retryIfNeeded(8) {
|
val sendPromise = retryIfNeeded(8) {
|
||||||
sendPairingAuthorisationMessage(context, pairingAuthorisation.secondaryDevicePublicKey, signedPairingAuthorisation)
|
sendPairingAuthorisationMessage(context, address.serialize(), signedPairingAuthorisation)
|
||||||
}.fail {
|
}.fail {
|
||||||
Log.d("Loki", "Failed to send pairing authorization message to ${pairingAuthorisation.secondaryDevicePublicKey}.")
|
Log.d("Loki", "Failed to send pairing authorization message to ${address.serialize()}.")
|
||||||
}
|
}
|
||||||
|
|
||||||
val updatePromise = LokiStorageAPI.shared.updateUserDeviceMappings().fail {
|
val updatePromise = LokiStorageAPI.shared.updateUserDeviceMappings().fail {
|
||||||
@ -138,7 +140,7 @@ fun signAndSendPairingAuthorisationMessage(context: Context, pairingAuthorisatio
|
|||||||
Log.d("Loki", "Successfully pairing with a secondary device! Syncing contacts.")
|
Log.d("Loki", "Successfully pairing with a secondary device! Syncing contacts.")
|
||||||
// Send out sync contact after a delay
|
// Send out sync contact after a delay
|
||||||
Timer().schedule(3000) {
|
Timer().schedule(3000) {
|
||||||
MessageSender.syncAllContacts(context)
|
MessageSender.syncAllContacts(context, address)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -81,8 +81,8 @@ public class MessageSender {
|
|||||||
|
|
||||||
private enum MessageType { TEXT, MEDIA }
|
private enum MessageType { TEXT, MEDIA }
|
||||||
|
|
||||||
public static void syncAllContacts(Context context) {
|
public static void syncAllContacts(Context context, Address recipient) {
|
||||||
ApplicationContext.getInstance(context).getJobManager().add(new MultiDeviceContactUpdateJob(context, true));
|
ApplicationContext.getInstance(context).getJobManager().add(new MultiDeviceContactUpdateJob(context, recipient, true));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
Loading…
x
Reference in New Issue
Block a user