diff --git a/src/org/thoughtcrime/securesms/jobs/MultiDeviceContactUpdateJob.java b/src/org/thoughtcrime/securesms/jobs/MultiDeviceContactUpdateJob.java index a10caa0edf..7ae1a13782 100644 --- a/src/org/thoughtcrime/securesms/jobs/MultiDeviceContactUpdateJob.java +++ b/src/org/thoughtcrime/securesms/jobs/MultiDeviceContactUpdateJob.java @@ -15,6 +15,7 @@ import org.thoughtcrime.securesms.contacts.ContactAccessor.ContactData; import org.thoughtcrime.securesms.crypto.ProfileKeyUtil; import org.thoughtcrime.securesms.crypto.UnidentifiedAccessUtil; import org.thoughtcrime.securesms.database.Address; +import org.thoughtcrime.securesms.database.Database; import org.thoughtcrime.securesms.database.DatabaseFactory; import org.thoughtcrime.securesms.database.IdentityDatabase; import org.thoughtcrime.securesms.dependencies.InjectableType; @@ -38,6 +39,7 @@ import org.whispersystems.signalservice.api.messages.multidevice.SignalServiceSy import org.whispersystems.signalservice.api.messages.multidevice.VerifiedMessage; import org.whispersystems.signalservice.api.push.exceptions.PushNetworkException; import org.whispersystems.signalservice.api.util.InvalidNumberException; +import org.whispersystems.signalservice.loki.messaging.LokiThreadFriendRequestStatus; import java.io.ByteArrayInputStream; import java.io.File; @@ -83,7 +85,7 @@ public class MultiDeviceContactUpdateJob extends BaseJob implements InjectableTy .addConstraint(NetworkConstraint.KEY) .setQueue("MultiDeviceContactUpdateJob") .setLifespan(TimeUnit.DAYS.toMillis(1)) - .setMaxAttempts(Parameters.UNLIMITED) + .setMaxAttempts(3) .build(), address, forceSync); @@ -126,6 +128,9 @@ public class MultiDeviceContactUpdateJob extends BaseJob implements InjectableTy private void generateSingleContactUpdate(@NonNull Address address) throws IOException, UntrustedIdentityException, NetworkException { + // Loki - Only sync regular contacts + if (!address.isPhone()) { return; } + File contactDataFile = createTempFile("multidevice-contact-update"); try { @@ -134,16 +139,19 @@ public class MultiDeviceContactUpdateJob extends BaseJob implements InjectableTy Optional identityRecord = DatabaseFactory.getIdentityDatabase(context).getIdentity(address); Optional verifiedMessage = getVerifiedMessage(recipient, identityRecord); - out.write(new DeviceContact(address.toPhoneString(), - Optional.fromNullable(recipient.getName()), - getAvatar(recipient.getContactUri()), - Optional.fromNullable(recipient.getColor().serialize()), - verifiedMessage, - Optional.fromNullable(recipient.getProfileKey()), - recipient.isBlocked(), - recipient.getExpireMessages() > 0 ? - Optional.of(recipient.getExpireMessages()) : - Optional.absent())); + // Loki - Only sync contacts we are friends with + if (getFriendRequestStatus(recipient) == LokiThreadFriendRequestStatus.FRIENDS) { + out.write(new DeviceContact(address.toPhoneString(), + Optional.fromNullable(recipient.getName()), + getAvatar(recipient.getContactUri()), + Optional.fromNullable(recipient.getColor().serialize()), + verifiedMessage, + Optional.fromNullable(recipient.getProfileKey()), + recipient.isBlocked(), + recipient.getExpireMessages() > 0 ? + Optional.of(recipient.getExpireMessages()) : + Optional.absent())); + } out.close(); sendUpdate(messageSender, contactDataFile, false); @@ -158,11 +166,6 @@ public class MultiDeviceContactUpdateJob extends BaseJob implements InjectableTy 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); @@ -189,13 +192,16 @@ public class MultiDeviceContactUpdateJob extends BaseJob implements InjectableTy Recipient recipient = Recipient.from(context, address, false); Optional identity = DatabaseFactory.getIdentityDatabase(context).getIdentity(address); Optional verified = getVerifiedMessage(recipient, identity); - Optional name = Optional.fromNullable(contactData.name); + Optional name = Optional.fromNullable(DatabaseFactory.getLokiUserDatabase(context).getDisplayName(address.serialize())); 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(); - out.write(new DeviceContact(address.toPhoneString(), name, getAvatar(contactUri), color, verified, profileKey, blocked, expireTimer)); + // Loki - Only sync contacts we are friends with + if (getFriendRequestStatus(recipient) == LokiThreadFriendRequestStatus.FRIENDS) { + out.write(new DeviceContact(address.toPhoneString(), name, getAvatar(contactUri), color, verified, profileKey, blocked, expireTimer)); + } } if (ProfileKeyUtil.hasProfileKey(context)) { @@ -216,6 +222,11 @@ public class MultiDeviceContactUpdateJob extends BaseJob implements InjectableTy } } + private LokiThreadFriendRequestStatus getFriendRequestStatus(Recipient recipient) { + long threadId = DatabaseFactory.getThreadDatabase(context).getThreadIdIfExistsFor(recipient); + return DatabaseFactory.getLokiThreadDatabase(context).getFriendRequestStatus(threadId); + } + @Override public boolean onShouldRetry(@NonNull Exception exception) { if (exception instanceof PushNetworkException) return true; @@ -239,7 +250,6 @@ public class MultiDeviceContactUpdateJob extends BaseJob implements InjectableTy .build(); try { - // TODO: Message ID messageSender.sendMessage(0, SignalServiceSyncMessage.forContacts(new ContactsMessage(attachmentStream, complete)), UnidentifiedAccessUtil.getAccessForSync(context)); } catch (IOException ioe) { @@ -319,6 +329,9 @@ public class MultiDeviceContactUpdateJob extends BaseJob implements InjectableTy default: throw new AssertionError("Unknown state: " + identity.get().getVerifiedStatus()); } + // Loki - For now always set to verified + state = VerifiedMessage.VerifiedState.VERIFIED; + return Optional.of(new VerifiedMessage(destination, identityKey, state, System.currentTimeMillis())); } diff --git a/src/org/thoughtcrime/securesms/jobs/PushDecryptJob.java b/src/org/thoughtcrime/securesms/jobs/PushDecryptJob.java index b42b07ce76..347314f910 100644 --- a/src/org/thoughtcrime/securesms/jobs/PushDecryptJob.java +++ b/src/org/thoughtcrime/securesms/jobs/PushDecryptJob.java @@ -1060,6 +1060,7 @@ public class PushDecryptJob extends BaseJob implements InjectableType { DatabaseFactory.getLokiAPIDatabase(context).removePairingAuthorisations(userHexEncodedPublicKey); DatabaseFactory.getLokiAPIDatabase(context).insertOrUpdatePairingAuthorisation(authorisation); TextSecurePreferences.setMasterHexEncodedPublicKey(context, authorisation.getPrimaryDevicePublicKey()); + TextSecurePreferences.setMultiDevice(context, true); // Send a background message to the primary device MessageSender.sendBackgroundMessage(context, authorisation.getPrimaryDevicePublicKey()); // Propagate the updates to the file server diff --git a/src/org/thoughtcrime/securesms/loki/LokiThreadDatabase.kt b/src/org/thoughtcrime/securesms/loki/LokiThreadDatabase.kt index 4c177bc108..3b66359ea9 100644 --- a/src/org/thoughtcrime/securesms/loki/LokiThreadDatabase.kt +++ b/src/org/thoughtcrime/securesms/loki/LokiThreadDatabase.kt @@ -41,6 +41,8 @@ class LokiThreadDatabase(context: Context, helper: SQLCipherOpenHelper) : Databa } fun getFriendRequestStatus(threadID: Long): LokiThreadFriendRequestStatus { + if (threadID < 0) { return LokiThreadFriendRequestStatus.NONE } + val database = databaseHelper.readableDatabase val result = database.get(friendRequestTableName, "${Companion.threadID} = ?", arrayOf( threadID.toString() )) { cursor -> cursor.getInt(friendRequestStatus) @@ -53,6 +55,8 @@ class LokiThreadDatabase(context: Context, helper: SQLCipherOpenHelper) : Databa } override fun setFriendRequestStatus(threadID: Long, friendRequestStatus: LokiThreadFriendRequestStatus) { + if (threadID < 0) { return } + val database = databaseHelper.writableDatabase val contentValues = ContentValues(2) contentValues.put(Companion.threadID, threadID) diff --git a/src/org/thoughtcrime/securesms/loki/MultiDeviceUtilities.kt b/src/org/thoughtcrime/securesms/loki/MultiDeviceUtilities.kt index f412564805..060cdda1a9 100644 --- a/src/org/thoughtcrime/securesms/loki/MultiDeviceUtilities.kt +++ b/src/org/thoughtcrime/securesms/loki/MultiDeviceUtilities.kt @@ -118,6 +118,7 @@ fun signAndSendPairingAuthorisationMessage(context: Context, pairingAuthorisatio Log.d("Loki", "Failed to send pairing authorization message to ${pairingAuthorisation.secondaryDevicePublicKey}.") } DatabaseFactory.getLokiAPIDatabase(context).insertOrUpdatePairingAuthorisation(signedPairingAuthorisation) + TextSecurePreferences.setMultiDevice(context, true) // Call function after a short delay Handler().postDelayed({ LokiStorageAPI.shared.updateUserDeviceMappings().fail {