diff --git a/libsignal/service/protobuf/SignalService.proto b/libsignal/service/protobuf/SignalService.proto index 42ae35c84f..40991aa2f7 100644 --- a/libsignal/service/protobuf/SignalService.proto +++ b/libsignal/service/protobuf/SignalService.proto @@ -402,15 +402,17 @@ message ContactDetails { optional uint32 length = 2; } - optional string number = 1; - optional string uuid = 9; - optional string name = 2; - optional Avatar avatar = 3; - optional string color = 4; - optional Verified verified = 5; - optional bytes profileKey = 6; - optional bool blocked = 7; - optional uint32 expireTimer = 8; + optional string number = 1; + optional string uuid = 9; + optional string name = 2; + optional Avatar avatar = 3; + optional string color = 4; + optional Verified verified = 5; + optional bytes profileKey = 6; + optional bool blocked = 7; + optional uint32 expireTimer = 8; + optional uint32 inboxPosition = 10; + optional bool archived = 11; } message GroupDetails { @@ -424,13 +426,15 @@ message GroupDetails { optional string e164 = 2; } - optional bytes id = 1; - optional string name = 2; - repeated string membersE164 = 3; - repeated Member members = 9; - optional Avatar avatar = 4; - optional bool active = 5 [default = true]; - optional uint32 expireTimer = 6; - optional string color = 7; - optional bool blocked = 8; + optional bytes id = 1; + optional string name = 2; + repeated string membersE164 = 3; + repeated Member members = 9; + optional Avatar avatar = 4; + optional bool active = 5 [default = true]; + optional uint32 expireTimer = 6; + optional string color = 7; + optional bool blocked = 8; + optional uint32 inboxPosition = 10; + optional bool archived = 11; } diff --git a/libsignal/service/src/main/java/org/whispersystems/signalservice/api/messages/multidevice/DeviceContact.java b/libsignal/service/src/main/java/org/whispersystems/signalservice/api/messages/multidevice/DeviceContact.java index 839a86fdca..5412b318ba 100644 --- a/libsignal/service/src/main/java/org/whispersystems/signalservice/api/messages/multidevice/DeviceContact.java +++ b/libsignal/service/src/main/java/org/whispersystems/signalservice/api/messages/multidevice/DeviceContact.java @@ -20,14 +20,19 @@ public class DeviceContact { private final Optional profileKey; private final boolean blocked; private final Optional expirationTimer; + private final Optional inboxPosition; + private final boolean archived; - public DeviceContact(SignalServiceAddress address, Optional name, + public DeviceContact(SignalServiceAddress address, + Optional name, Optional avatar, Optional color, Optional verified, Optional profileKey, boolean blocked, - Optional expirationTimer) + Optional expirationTimer, + Optional inboxPosition, + boolean archived) { this.address = address; this.name = name; @@ -37,6 +42,8 @@ public class DeviceContact { this.profileKey = profileKey; this.blocked = blocked; this.expirationTimer = expirationTimer; + this.inboxPosition = inboxPosition; + this.archived = archived; } public Optional getAvatar() { @@ -70,4 +77,12 @@ public class DeviceContact { public Optional getExpirationTimer() { return expirationTimer; } + + public Optional getInboxPosition() { + return inboxPosition; + } + + public boolean isArchived() { + return archived; + } } diff --git a/libsignal/service/src/main/java/org/whispersystems/signalservice/api/messages/multidevice/DeviceContactsInputStream.java b/libsignal/service/src/main/java/org/whispersystems/signalservice/api/messages/multidevice/DeviceContactsInputStream.java index 46061c69e4..29161cef6b 100644 --- a/libsignal/service/src/main/java/org/whispersystems/signalservice/api/messages/multidevice/DeviceContactsInputStream.java +++ b/libsignal/service/src/main/java/org/whispersystems/signalservice/api/messages/multidevice/DeviceContactsInputStream.java @@ -39,14 +39,16 @@ public class DeviceContactsInputStream extends ChunkedInputStream { throw new IOException("Missing contact address!"); } - SignalServiceAddress address = new SignalServiceAddress(UuidUtil.parseOrNull(details.getUuid()), details.getNumber()); - Optional name = Optional.fromNullable(details.getName()); - Optional avatar = Optional.absent(); - Optional color = details.hasColor() ? Optional.of(details.getColor()) : Optional.absent(); - Optional verified = Optional.absent(); - Optional profileKey = Optional.absent(); - boolean blocked = false; - Optional expireTimer = Optional.absent(); + SignalServiceAddress address = new SignalServiceAddress(UuidUtil.parseOrNull(details.getUuid()), details.getNumber()); + Optional name = Optional.fromNullable(details.getName()); + Optional avatar = Optional.absent(); + Optional color = details.hasColor() ? Optional.of(details.getColor()) : Optional.absent(); + Optional verified = Optional.absent(); + Optional profileKey = Optional.absent(); + boolean blocked = false; + Optional expireTimer = Optional.absent(); + Optional inboxPosition = Optional.absent(); + boolean archived = false; if (details.hasAvatar()) { long avatarLength = details.getAvatar().getLength(); @@ -89,9 +91,14 @@ public class DeviceContactsInputStream extends ChunkedInputStream { expireTimer = Optional.of(details.getExpireTimer()); } - blocked = details.getBlocked(); + if (details.hasInboxPosition()) { + inboxPosition = Optional.of(details.getInboxPosition()); + } - return new DeviceContact(address, name, avatar, color, verified, profileKey, blocked, expireTimer); + blocked = details.getBlocked(); + archived = details.getArchived(); + + return new DeviceContact(address, name, avatar, color, verified, profileKey, blocked, expireTimer, inboxPosition, archived); } } diff --git a/libsignal/service/src/main/java/org/whispersystems/signalservice/api/messages/multidevice/DeviceContactsOutputStream.java b/libsignal/service/src/main/java/org/whispersystems/signalservice/api/messages/multidevice/DeviceContactsOutputStream.java index ca17e5b147..9b4e35729d 100644 --- a/libsignal/service/src/main/java/org/whispersystems/signalservice/api/messages/multidevice/DeviceContactsOutputStream.java +++ b/libsignal/service/src/main/java/org/whispersystems/signalservice/api/messages/multidevice/DeviceContactsOutputStream.java @@ -92,7 +92,12 @@ public class DeviceContactsOutputStream extends ChunkedOutputStream { contactDetails.setExpireTimer(contact.getExpirationTimer().get()); } + if (contact.getInboxPosition().isPresent()) { + contactDetails.setInboxPosition(contact.getInboxPosition().get()); + } + contactDetails.setBlocked(contact.isBlocked()); + contactDetails.setArchived(contact.isArchived()); byte[] serializedContactDetails = contactDetails.build().toByteArray(); diff --git a/libsignal/service/src/main/java/org/whispersystems/signalservice/api/messages/multidevice/DeviceGroup.java b/libsignal/service/src/main/java/org/whispersystems/signalservice/api/messages/multidevice/DeviceGroup.java index ca7d89a014..fff5046210 100644 --- a/libsignal/service/src/main/java/org/whispersystems/signalservice/api/messages/multidevice/DeviceGroup.java +++ b/libsignal/service/src/main/java/org/whispersystems/signalservice/api/messages/multidevice/DeviceGroup.java @@ -22,11 +22,19 @@ public class DeviceGroup { private final Optional expirationTimer; private final Optional color; private final boolean blocked; + private final Optional inboxPosition; + private final boolean archived; - public DeviceGroup(byte[] id, Optional name, List members, + public DeviceGroup(byte[] id, + Optional name, + List members, Optional avatar, - boolean active, Optional expirationTimer, - Optional color, boolean blocked) + boolean active, + Optional expirationTimer, + Optional color, + boolean blocked, + Optional inboxPosition, + boolean archived) { this.id = id; this.name = name; @@ -36,6 +44,8 @@ public class DeviceGroup { this.expirationTimer = expirationTimer; this.color = color; this.blocked = blocked; + this.inboxPosition = inboxPosition; + this.archived = archived; } public Optional getAvatar() { @@ -69,4 +79,12 @@ public class DeviceGroup { public boolean isBlocked() { return blocked; } + + public Optional getInboxPosition() { + return inboxPosition; + } + + public boolean isArchived() { + return archived; + } } diff --git a/libsignal/service/src/main/java/org/whispersystems/signalservice/api/messages/multidevice/DeviceGroupsInputStream.java b/libsignal/service/src/main/java/org/whispersystems/signalservice/api/messages/multidevice/DeviceGroupsInputStream.java index b8addddcbd..a30224f9d0 100644 --- a/libsignal/service/src/main/java/org/whispersystems/signalservice/api/messages/multidevice/DeviceGroupsInputStream.java +++ b/libsignal/service/src/main/java/org/whispersystems/signalservice/api/messages/multidevice/DeviceGroupsInputStream.java @@ -44,6 +44,8 @@ public class DeviceGroupsInputStream extends ChunkedInputStream{ Optional expirationTimer = Optional.absent(); Optional color = Optional.fromNullable(details.getColor()); boolean blocked = details.getBlocked(); + Optional inboxPosition = Optional.absent(); + boolean archived = false; if (details.hasAvatar()) { long avatarLength = details.getAvatar().getLength(); @@ -66,7 +68,15 @@ public class DeviceGroupsInputStream extends ChunkedInputStream{ } } - return new DeviceGroup(id, name, addressMembers, avatar, active, expirationTimer, color, blocked); + if (details.hasInboxPosition()) { + inboxPosition = Optional.of(details.getInboxPosition()); + } + + if (details.hasArchived()) { + archived = details.getArchived(); + } + + return new DeviceGroup(id, name, addressMembers, avatar, active, expirationTimer, color, blocked, inboxPosition, archived); } } diff --git a/libsignal/service/src/main/java/org/whispersystems/signalservice/api/messages/multidevice/DeviceGroupsOutputStream.java b/libsignal/service/src/main/java/org/whispersystems/signalservice/api/messages/multidevice/DeviceGroupsOutputStream.java index b59c17ae21..3db85b6429 100644 --- a/libsignal/service/src/main/java/org/whispersystems/signalservice/api/messages/multidevice/DeviceGroupsOutputStream.java +++ b/libsignal/service/src/main/java/org/whispersystems/signalservice/api/messages/multidevice/DeviceGroupsOutputStream.java @@ -83,6 +83,11 @@ public class DeviceGroupsOutputStream extends ChunkedOutputStream { groupDetails.addAllMembersE164(membersE164); groupDetails.setActive(group.isActive()); groupDetails.setBlocked(group.isBlocked()); + groupDetails.setArchived(group.isArchived()); + + if (group.getInboxPosition().isPresent()) { + groupDetails.setInboxPosition(group.getInboxPosition().get()); + } byte[] serializedContactDetails = groupDetails.build().toByteArray(); diff --git a/src/org/thoughtcrime/securesms/database/RecipientDatabase.java b/src/org/thoughtcrime/securesms/database/RecipientDatabase.java index 9c0a4375e7..42c941bfc4 100644 --- a/src/org/thoughtcrime/securesms/database/RecipientDatabase.java +++ b/src/org/thoughtcrime/securesms/database/RecipientDatabase.java @@ -1075,6 +1075,25 @@ public class RecipientDatabase extends Database { return databaseHelper.getReadableDatabase().query(TABLE_NAME, SEARCH_PROJECTION, selection, args, null, null, null); } + public @NonNull List getRecipientsForMultiDeviceSync() { + String subquery = "SELECT " + ThreadDatabase.TABLE_NAME + "." + ThreadDatabase.RECIPIENT_ID + " FROM " + ThreadDatabase.TABLE_NAME; + String selection = REGISTERED + " = ? AND " + + GROUP_ID + " IS NULL AND " + + ID + " != ? AND " + + "(" + SYSTEM_DISPLAY_NAME + " NOT NULL OR " + ID + " IN (" + subquery + "))"; + String[] args = new String[] { String.valueOf(RegisteredState.REGISTERED.getId()), Recipient.self().getId().serialize() }; + + List recipients = new ArrayList<>(); + + try (Cursor cursor = databaseHelper.getReadableDatabase().query(TABLE_NAME, ID_PROJECTION, selection, args, null, null, null)) { + while (cursor != null && cursor.moveToNext()) { + recipients.add(Recipient.resolved(RecipientId.from(cursor.getLong(cursor.getColumnIndexOrThrow(ID))))); + } + } + + return recipients; + } + public void applyBlockedUpdate(@NonNull List blocked, List groupIds) { List blockedE164 = Stream.of(blocked) .filter(b -> b.getNumber().isPresent()) diff --git a/src/org/thoughtcrime/securesms/database/ThreadDatabase.java b/src/org/thoughtcrime/securesms/database/ThreadDatabase.java index 8fcd7f2e56..336cd327e4 100644 --- a/src/org/thoughtcrime/securesms/database/ThreadDatabase.java +++ b/src/org/thoughtcrime/securesms/database/ThreadDatabase.java @@ -52,8 +52,11 @@ import org.whispersystems.libsignal.util.guava.Optional; import java.io.Closeable; import java.io.IOException; +import java.util.HashMap; +import java.util.HashSet; import java.util.LinkedList; import java.util.List; +import java.util.Map; import java.util.Set; public class ThreadDatabase extends Database { @@ -418,6 +421,36 @@ public class ThreadDatabase extends Database { return getConversationList("1"); } + public @NonNull Set getArchivedRecipients() { + Set archived = new HashSet<>(); + + try (Cursor cursor = DatabaseFactory.getThreadDatabase(context).getArchivedConversationList()) { + while (cursor != null && cursor.moveToNext()) { + archived.add(RecipientId.from(cursor.getLong(cursor.getColumnIndexOrThrow(ThreadDatabase.RECIPIENT_ID)))); + } + } + + return archived; + } + + public @NonNull Map getInboxPositions() { + SQLiteDatabase db = databaseHelper.getReadableDatabase(); + String query = createQuery(MESSAGE_COUNT + " != ?", 0); + + Map positions = new HashMap<>(); + + try (Cursor cursor = db.rawQuery(query, new String[] { "0" })) { + int i = 0; + while (cursor != null && cursor.moveToNext()) { + RecipientId recipientId = RecipientId.from(cursor.getLong(cursor.getColumnIndexOrThrow(ThreadDatabase.RECIPIENT_ID))); + positions.put(recipientId, i); + i++; + } + } + + return positions; + } + private Cursor getConversationList(String archived) { SQLiteDatabase db = databaseHelper.getReadableDatabase(); String query = createQuery(ARCHIVED + " = ? AND " + MESSAGE_COUNT + " != 0", 0); diff --git a/src/org/thoughtcrime/securesms/jobs/MultiDeviceContactUpdateJob.java b/src/org/thoughtcrime/securesms/jobs/MultiDeviceContactUpdateJob.java index 63f4c9be4d..6629f5e635 100644 --- a/src/org/thoughtcrime/securesms/jobs/MultiDeviceContactUpdateJob.java +++ b/src/org/thoughtcrime/securesms/jobs/MultiDeviceContactUpdateJob.java @@ -1,6 +1,5 @@ package org.thoughtcrime.securesms.jobs; -import android.Manifest; import android.content.res.AssetFileDescriptor; import android.database.Cursor; import android.net.Uri; @@ -9,18 +8,16 @@ import androidx.annotation.NonNull; import androidx.annotation.Nullable; import org.thoughtcrime.securesms.ApplicationContext; -import org.thoughtcrime.securesms.contacts.ContactAccessor; -import org.thoughtcrime.securesms.contacts.ContactAccessor.ContactData; import org.thoughtcrime.securesms.crypto.ProfileKeyUtil; import org.thoughtcrime.securesms.crypto.UnidentifiedAccessUtil; import org.thoughtcrime.securesms.database.DatabaseFactory; import org.thoughtcrime.securesms.database.IdentityDatabase; +import org.thoughtcrime.securesms.database.ThreadDatabase; import org.thoughtcrime.securesms.dependencies.ApplicationDependencies; import org.thoughtcrime.securesms.jobmanager.Data; import org.thoughtcrime.securesms.jobmanager.Job; import org.thoughtcrime.securesms.jobmanager.impl.NetworkConstraint; import org.thoughtcrime.securesms.logging.Log; -import org.thoughtcrime.securesms.permissions.Permissions; import org.thoughtcrime.securesms.recipients.Recipient; import org.thoughtcrime.securesms.recipients.RecipientId; import org.thoughtcrime.securesms.recipients.RecipientUtil; @@ -45,7 +42,11 @@ import java.io.File; import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.IOException; -import java.util.Collection; +import java.util.HashMap; +import java.util.HashSet; +import java.util.List; +import java.util.Map; +import java.util.Set; import java.util.concurrent.TimeUnit; public class MultiDeviceContactUpdateJob extends BaseJob { @@ -128,17 +129,20 @@ public class MultiDeviceContactUpdateJob extends BaseJob { Recipient recipient = Recipient.resolved(recipientId); Optional identityRecord = DatabaseFactory.getIdentityDatabase(context).getIdentity(recipient.getId()); Optional verifiedMessage = getVerifiedMessage(recipient, identityRecord); + Map inboxPositions = DatabaseFactory.getThreadDatabase(context).getInboxPositions(); + Set archived = DatabaseFactory.getThreadDatabase(context).getArchivedRecipients(); out.write(new DeviceContact(RecipientUtil.toSignalServiceAddress(context, recipient), Optional.of(recipient.getDisplayName(context)), - getAvatar(recipient.getContactUri()), + getSystemAvatar(recipient.getContactUri()), Optional.fromNullable(recipient.getColor().serialize()), verifiedMessage, Optional.fromNullable(recipient.getProfileKey()), recipient.isBlocked(), - recipient.getExpireMessages() > 0 ? - Optional.of(recipient.getExpireMessages()) : - Optional.absent())); + recipient.getExpireMessages() > 0 ? Optional.of(recipient.getExpireMessages()) + : Optional.absent(), + Optional.fromNullable(inboxPositions.get(recipientId)), + archived.contains(recipientId))); out.close(); sendUpdate(ApplicationDependencies.getSignalServiceMessageSender(), contactDataFile, false); @@ -153,11 +157,6 @@ public class MultiDeviceContactUpdateJob extends BaseJob { private void generateFullContactUpdate() throws IOException, UntrustedIdentityException, NetworkException { - if (!Permissions.hasAny(context, Manifest.permission.READ_CONTACTS, Manifest.permission.WRITE_CONTACTS)) { - Log.w(TAG, "No contact permissions, skipping multi-device contact update..."); - return; - } - boolean isAppVisible = ApplicationContext.getInstance(context).isAppVisible(); long timeSinceLastSync = System.currentTimeMillis() - TextSecurePreferences.getLastFullContactSyncTime(context); @@ -175,30 +174,45 @@ public class MultiDeviceContactUpdateJob extends BaseJob { File contactDataFile = createTempFile("multidevice-contact-update"); try { - DeviceContactsOutputStream out = new DeviceContactsOutputStream(new FileOutputStream(contactDataFile)); - Collection contacts = ContactAccessor.getInstance().getContactsWithPush(context); + DeviceContactsOutputStream out = new DeviceContactsOutputStream(new FileOutputStream(contactDataFile)); + List recipients = DatabaseFactory.getRecipientDatabase(context).getRecipientsForMultiDeviceSync(); + Map inboxPositions = DatabaseFactory.getThreadDatabase(context).getInboxPositions(); + Set archived = DatabaseFactory.getThreadDatabase(context).getArchivedRecipients(); - for (ContactData contactData : contacts) { - Uri contactUri = Uri.withAppendedPath(ContactsContract.Contacts.CONTENT_URI, String.valueOf(contactData.id)); - Recipient recipient = Recipient.external(context, contactData.numbers.get(0).number); - Optional identity = DatabaseFactory.getIdentityDatabase(context).getIdentity(recipient.getId()); - Optional verified = getVerifiedMessage(recipient, identity); - Optional name = Optional.fromNullable(contactData.name); - Optional color = Optional.of(recipient.getColor().serialize()); - Optional profileKey = Optional.fromNullable(recipient.getProfileKey()); - boolean blocked = recipient.isBlocked(); - Optional expireTimer = recipient.getExpireMessages() > 0 ? Optional.of(recipient.getExpireMessages()) : Optional.absent(); + for (Recipient recipient : recipients) { + Optional identity = DatabaseFactory.getIdentityDatabase(context).getIdentity(recipient.getId()); + Optional verified = getVerifiedMessage(recipient, identity); + Optional name = Optional.fromNullable(recipient.getName(context)); + Optional color = Optional.of(recipient.getColor().serialize()); + Optional profileKey = Optional.fromNullable(recipient.getProfileKey()); + boolean blocked = recipient.isBlocked(); + Optional expireTimer = recipient.getExpireMessages() > 0 ? Optional.of(recipient.getExpireMessages()) : Optional.absent(); + Optional inboxPosition = Optional.fromNullable(inboxPositions.get(recipient.getId())); - out.write(new DeviceContact(RecipientUtil.toSignalServiceAddress(context, recipient), name, getAvatar(contactUri), color, verified, profileKey, blocked, expireTimer)); + out.write(new DeviceContact(RecipientUtil.toSignalServiceAddress(context, recipient), + name, + getSystemAvatar(recipient.getContactUri()), + color, + verified, + profileKey, + blocked, + expireTimer, + inboxPosition, + archived.contains(recipient.getId()))); } if (ProfileKeyUtil.hasProfileKey(context)) { Recipient self = Recipient.self(); - out.write(new DeviceContact(RecipientUtil.toSignalServiceAddress(context, Recipient.self()), - Optional.absent(), Optional.absent(), - Optional.of(self.getColor().serialize()), Optional.absent(), + out.write(new DeviceContact(RecipientUtil.toSignalServiceAddress(context, self), + Optional.absent(), + Optional.absent(), + Optional.of(self.getColor().serialize()), + Optional.absent(), Optional.of(ProfileKeyUtil.getProfileKey(context)), - false, self.getExpireMessages() > 0 ? Optional.of(self.getExpireMessages()) : Optional.absent())); + false, + self.getExpireMessages() > 0 ? Optional.of(self.getExpireMessages()) : Optional.absent(), + Optional.fromNullable(inboxPositions.get(self.getId())), + archived.contains(self.getId()))); } out.close(); @@ -241,7 +255,7 @@ public class MultiDeviceContactUpdateJob extends BaseJob { } } - private Optional getAvatar(@Nullable Uri uri) throws IOException { + private Optional getSystemAvatar(@Nullable Uri uri) { if (uri == null) { return Optional.absent(); } diff --git a/src/org/thoughtcrime/securesms/jobs/MultiDeviceGroupUpdateJob.java b/src/org/thoughtcrime/securesms/jobs/MultiDeviceGroupUpdateJob.java index 27a11882d2..58cb23e6ce 100644 --- a/src/org/thoughtcrime/securesms/jobs/MultiDeviceGroupUpdateJob.java +++ b/src/org/thoughtcrime/securesms/jobs/MultiDeviceGroupUpdateJob.java @@ -34,6 +34,8 @@ import java.io.FileOutputStream; import java.io.IOException; import java.util.LinkedList; import java.util.List; +import java.util.Map; +import java.util.Set; import java.util.concurrent.TimeUnit; public class MultiDeviceGroupUpdateJob extends BaseJob { @@ -90,15 +92,22 @@ public class MultiDeviceGroupUpdateJob extends BaseJob { members.add(RecipientUtil.toSignalServiceAddress(context, Recipient.resolved(member))); } - RecipientId recipientId = DatabaseFactory.getRecipientDatabase(context).getOrInsertFromGroupId(GroupUtil.getEncodedId(record.getId(), record.isMms())); - Recipient recipient = Recipient.resolved(recipientId); - Optional expirationTimer = recipient.getExpireMessages() > 0 ? Optional.of(recipient.getExpireMessages()) : Optional.absent(); + RecipientId recipientId = DatabaseFactory.getRecipientDatabase(context).getOrInsertFromGroupId(GroupUtil.getEncodedId(record.getId(), record.isMms())); + Recipient recipient = Recipient.resolved(recipientId); + Optional expirationTimer = recipient.getExpireMessages() > 0 ? Optional.of(recipient.getExpireMessages()) : Optional.absent(); + Map inboxPositions = DatabaseFactory.getThreadDatabase(context).getInboxPositions(); + Set archived = DatabaseFactory.getThreadDatabase(context).getArchivedRecipients(); - out.write(new DeviceGroup(record.getId(), Optional.fromNullable(record.getTitle()), - members, getAvatar(record.getAvatar()), - record.isActive(), expirationTimer, + out.write(new DeviceGroup(record.getId(), + Optional.fromNullable(record.getTitle()), + members, + getAvatar(record.getAvatar()), + record.isActive(), + expirationTimer, Optional.of(recipient.getColor().serialize()), - recipient.isBlocked())); + recipient.isBlocked(), + Optional.fromNullable(inboxPositions.get(recipientId)), + archived.contains(recipientId))); } } diff --git a/src/org/thoughtcrime/securesms/jobs/MultiDeviceProfileKeyUpdateJob.java b/src/org/thoughtcrime/securesms/jobs/MultiDeviceProfileKeyUpdateJob.java index 4f26dfc789..5e56634f02 100644 --- a/src/org/thoughtcrime/securesms/jobs/MultiDeviceProfileKeyUpdateJob.java +++ b/src/org/thoughtcrime/securesms/jobs/MultiDeviceProfileKeyUpdateJob.java @@ -75,7 +75,11 @@ public class MultiDeviceProfileKeyUpdateJob extends BaseJob { Optional.absent(), Optional.absent(), Optional.absent(), - profileKey, false, Optional.absent())); + profileKey, + false, + Optional.absent(), + Optional.absent(), + false)); out.close();