diff --git a/app/src/main/java/org/thoughtcrime/securesms/database/RecipientDatabase.java b/app/src/main/java/org/thoughtcrime/securesms/database/RecipientDatabase.java index 033d780c13f2fede1fc86f8ec2b4947245ef9836..0f8763e573dae21371173a1baff87b6842dddf2f 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/database/RecipientDatabase.java +++ b/app/src/main/java/org/thoughtcrime/securesms/database/RecipientDatabase.java @@ -2716,12 +2716,16 @@ public class RecipientDatabase extends Database { ApplicationDependencies.getRecipientCache().clear(); } - public void updateStorageKeys(@NonNull Map<RecipientId, byte[]> keys) { + public void updateStorageId(@NonNull RecipientId recipientId, byte[] id) { + updateStorageIds(Collections.singletonMap(recipientId, id)); + } + + public void updateStorageIds(@NonNull Map<RecipientId, byte[]> ids) { SQLiteDatabase db = databaseHelper.getWritableDatabase(); db.beginTransaction(); try { - for (Map.Entry<RecipientId, byte[]> entry : keys.entrySet()) { + for (Map.Entry<RecipientId, byte[]> entry : ids.entrySet()) { ContentValues values = new ContentValues(); values.put(STORAGE_SERVICE_ID, Base64.encodeBytes(entry.getValue())); db.update(TABLE_NAME, values, ID_WHERE, new String[] { entry.getKey().serialize() }); @@ -2732,7 +2736,7 @@ public class RecipientDatabase extends Database { db.endTransaction(); } - for (RecipientId id : keys.keySet()) { + for (RecipientId id : ids.keySet()) { Recipient.live(id).refresh(); } } diff --git a/app/src/main/java/org/thoughtcrime/securesms/jobs/StorageSyncJob.java b/app/src/main/java/org/thoughtcrime/securesms/jobs/StorageSyncJob.java index 8a3a7e897c05c0422b04b3159568054a0a6f69e4..3a394c01de06be794a583bafd9c7a336e3f9f769 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/jobs/StorageSyncJob.java +++ b/app/src/main/java/org/thoughtcrime/securesms/jobs/StorageSyncJob.java @@ -279,7 +279,7 @@ public class StorageSyncJob extends BaseJob { clearIds.add(Recipient.self().getId()); recipientDatabase.clearDirtyState(clearIds); - recipientDatabase.updateStorageKeys(localWriteResult.get().getStorageKeyUpdates()); + recipientDatabase.updateStorageIds(localWriteResult.get().getStorageKeyUpdates()); needsMultiDeviceSync = true; diff --git a/app/src/main/java/org/thoughtcrime/securesms/jobs/StorageSyncJobV2.java b/app/src/main/java/org/thoughtcrime/securesms/jobs/StorageSyncJobV2.java index 5a7f455d4b67813a6f4084bacfe14a6e3c89c541..3c8f8e56f6dd70dd0a4a319aa9ac0f7885101080 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/jobs/StorageSyncJobV2.java +++ b/app/src/main/java/org/thoughtcrime/securesms/jobs/StorageSyncJobV2.java @@ -395,7 +395,7 @@ public class StorageSyncJobV2 extends BaseJob { clearIds.add(Recipient.self().getId()); recipientDatabase.clearDirtyState(clearIds); - recipientDatabase.updateStorageKeys(localWriteResult.get().getStorageKeyUpdates()); + recipientDatabase.updateStorageIds(localWriteResult.get().getStorageKeyUpdates()); needsMultiDeviceSync = true; diff --git a/app/src/main/java/org/thoughtcrime/securesms/storage/AccountRecordProcessor.java b/app/src/main/java/org/thoughtcrime/securesms/storage/AccountRecordProcessor.java index 3d405f35d69920912ea21f04cb94a5659113d669..3305167e9b171d928957e9c4e8e865ea545dcb2b 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/storage/AccountRecordProcessor.java +++ b/app/src/main/java/org/thoughtcrime/securesms/storage/AccountRecordProcessor.java @@ -9,19 +9,14 @@ import org.signal.core.util.logging.Log; import org.thoughtcrime.securesms.database.DatabaseFactory; import org.thoughtcrime.securesms.database.RecipientDatabase; import org.thoughtcrime.securesms.recipients.Recipient; -import org.thoughtcrime.securesms.recipients.RecipientId; import org.whispersystems.libsignal.util.guava.Optional; import org.whispersystems.signalservice.api.storage.SignalAccountRecord; import org.whispersystems.signalservice.api.storage.SignalAccountRecord.PinnedConversation; -import org.whispersystems.signalservice.api.storage.StorageId; import org.whispersystems.signalservice.internal.storage.protos.AccountRecord; import java.util.Arrays; -import java.util.Collection; -import java.util.HashSet; import java.util.List; import java.util.Objects; -import java.util.Set; /** * Processes {@link SignalAccountRecord}s. Unlike some other {@link StorageRecordProcessor}s, this @@ -66,7 +61,7 @@ public class AccountRecordProcessor extends DefaultStorageRecordProcessor<Signal } @Override - public @NonNull Optional<SignalAccountRecord> getMatching(@NonNull SignalAccountRecord record) { + public @NonNull Optional<SignalAccountRecord> getMatching(@NonNull SignalAccountRecord record, @NonNull StorageKeyGenerator keyGenerator) { return Optional.of(localAccountRecord); } diff --git a/app/src/main/java/org/thoughtcrime/securesms/storage/ContactRecordProcessor.java b/app/src/main/java/org/thoughtcrime/securesms/storage/ContactRecordProcessor.java index 71c73eacf9f7dc8cf3bc84efb4b65b4f0ff67e9e..c2ec660412e9c36080de7e1e477b8fb4a4a48c52 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/storage/ContactRecordProcessor.java +++ b/app/src/main/java/org/thoughtcrime/securesms/storage/ContactRecordProcessor.java @@ -16,9 +16,6 @@ import org.whispersystems.signalservice.api.storage.SignalContactRecord; import org.whispersystems.signalservice.internal.storage.protos.ContactRecord.IdentityState; import java.util.Arrays; -import java.util.Collection; -import java.util.LinkedList; -import java.util.List; import java.util.Objects; import java.util.UUID; @@ -63,13 +60,21 @@ public class ContactRecordProcessor extends DefaultStorageRecordProcessor<Signal } @Override - @NonNull Optional<SignalContactRecord> getMatching(@NonNull SignalContactRecord remote) { + @NonNull Optional<SignalContactRecord> getMatching(@NonNull SignalContactRecord remote, @NonNull StorageKeyGenerator keyGenerator) { SignalServiceAddress address = remote.getAddress(); Optional<RecipientId> byUuid = address.getUuid().isPresent() ? recipientDatabase.getByUuid(address.getUuid().get()) : Optional.absent(); Optional<RecipientId> byE164 = address.getNumber().isPresent() ? recipientDatabase.getByE164(address.getNumber().get()) : Optional.absent(); return byUuid.or(byE164).transform(recipientDatabase::getRecipientSettingsForSync) - .transform(StorageSyncModels::localToRemoteRecord) + .transform(settings -> { + if (settings.getStorageId() != null) { + return StorageSyncModels.localToRemoteRecord(settings); + } else { + Log.w(TAG, "Newly discovering a registered user via storage service. Saving a storageId for them."); + recipientDatabase.updateStorageId(settings.getId(), keyGenerator.generate()); + return StorageSyncModels.localToRemoteRecord(recipientDatabase.getRecipientSettingsForSync(settings.getId())); + } + }) .transform(r -> r.getContact().get()); } diff --git a/app/src/main/java/org/thoughtcrime/securesms/storage/DefaultStorageRecordProcessor.java b/app/src/main/java/org/thoughtcrime/securesms/storage/DefaultStorageRecordProcessor.java index e2a4beb61037adf5b55e382f51bb0bf2bf83dd07..2cc3b13325f78be648aeca44648ad63a8a4007ab 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/storage/DefaultStorageRecordProcessor.java +++ b/app/src/main/java/org/thoughtcrime/securesms/storage/DefaultStorageRecordProcessor.java @@ -51,7 +51,7 @@ abstract class DefaultStorageRecordProcessor<E extends SignalRecord> implements if (isInvalid(remote)) { remoteDeletes.add(remote); } else { - Optional<E> local = getMatching(remote); + Optional<E> local = getMatching(remote, keyGenerator); if (local.isPresent()) { E merged = merge(remote, local.get(), keyGenerator); @@ -88,7 +88,7 @@ abstract class DefaultStorageRecordProcessor<E extends SignalRecord> implements * Only records that pass the validity check (i.e. return false from {@link #isInvalid(SignalRecord)} * make it to here, so you can assume all records are valid. */ - abstract @NonNull Optional<E> getMatching(@NonNull E remote); + abstract @NonNull Optional<E> getMatching(@NonNull E remote, @NonNull StorageKeyGenerator keyGenerator); abstract @NonNull E merge(@NonNull E remote, @NonNull E local, @NonNull StorageKeyGenerator keyGenerator); abstract void insertLocal(@NonNull E record) throws IOException; diff --git a/app/src/main/java/org/thoughtcrime/securesms/storage/GroupV1RecordProcessor.java b/app/src/main/java/org/thoughtcrime/securesms/storage/GroupV1RecordProcessor.java index a3f99104e444f89e319ce8b45fba88027c44358d..8b5d57afe21ed07282742c0060d0b2b8e752efc7 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/storage/GroupV1RecordProcessor.java +++ b/app/src/main/java/org/thoughtcrime/securesms/storage/GroupV1RecordProcessor.java @@ -14,8 +14,6 @@ import org.thoughtcrime.securesms.groups.GroupId; import org.thoughtcrime.securesms.recipients.RecipientId; import org.whispersystems.libsignal.util.guava.Optional; import org.whispersystems.signalservice.api.storage.SignalGroupV1Record; -import org.whispersystems.signalservice.api.storage.SignalGroupV2Record; -import org.whispersystems.signalservice.api.storage.SignalStorageRecord; import java.util.Arrays; @@ -64,7 +62,7 @@ public final class GroupV1RecordProcessor extends DefaultStorageRecordProcessor< } @Override - @NonNull Optional<SignalGroupV1Record> getMatching(@NonNull SignalGroupV1Record record) { + @NonNull Optional<SignalGroupV1Record> getMatching(@NonNull SignalGroupV1Record record, @NonNull StorageKeyGenerator keyGenerator) { GroupId.V1 groupId = GroupId.v1orThrow(record.getGroupId()); Optional<RecipientId> recipientId = recipientDatabase.getByGroupId(groupId); diff --git a/app/src/main/java/org/thoughtcrime/securesms/storage/GroupV2RecordProcessor.java b/app/src/main/java/org/thoughtcrime/securesms/storage/GroupV2RecordProcessor.java index 8b65dbcb190ba4c6fa5f78a087f2d5754bf7469c..13ea8c9d4024dbe425211653b945856293b0d6b9 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/storage/GroupV2RecordProcessor.java +++ b/app/src/main/java/org/thoughtcrime/securesms/storage/GroupV2RecordProcessor.java @@ -13,10 +13,8 @@ import org.thoughtcrime.securesms.database.RecipientDatabase; import org.thoughtcrime.securesms.groups.GroupId; import org.thoughtcrime.securesms.groups.GroupsV1MigrationUtil; import org.thoughtcrime.securesms.recipients.RecipientId; -import org.thoughtcrime.securesms.util.ParcelUtil; import org.whispersystems.libsignal.util.guava.Optional; import org.whispersystems.signalservice.api.storage.SignalGroupV2Record; -import org.whispersystems.signalservice.internal.storage.protos.GroupV2Record; import java.io.IOException; import java.util.Arrays; @@ -46,7 +44,7 @@ public final class GroupV2RecordProcessor extends DefaultStorageRecordProcessor< } @Override - @NonNull Optional<SignalGroupV2Record> getMatching(@NonNull SignalGroupV2Record record) { + @NonNull Optional<SignalGroupV2Record> getMatching(@NonNull SignalGroupV2Record record, @NonNull StorageKeyGenerator keyGenerator) { GroupId.V2 groupId = GroupId.v2(record.getMasterKeyOrThrow()); Optional<RecipientId> recipientId = recipientDatabase.getByGroupId(groupId);