diff --git a/app/src/main/java/org/thoughtcrime/securesms/database/DatabaseFactory.java b/app/src/main/java/org/thoughtcrime/securesms/database/DatabaseFactory.java index f2264742ad..56b65a48ec 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/database/DatabaseFactory.java +++ b/app/src/main/java/org/thoughtcrime/securesms/database/DatabaseFactory.java @@ -41,29 +41,29 @@ public class DatabaseFactory { private static volatile DatabaseFactory instance; - private final SQLCipherOpenHelper databaseHelper; - private final SmsDatabase sms; - private final MmsDatabase mms; - private final AttachmentDatabase attachments; - private final MediaDatabase media; - private final ThreadDatabase thread; - private final MmsSmsDatabase mmsSmsDatabase; - private final IdentityDatabase identityDatabase; - private final DraftDatabase draftDatabase; - private final PushDatabase pushDatabase; - private final GroupDatabase groupDatabase; - private final RecipientDatabase recipientDatabase; - private final ContactsDatabase contactsDatabase; - private final GroupReceiptDatabase groupReceiptDatabase; - private final OneTimePreKeyDatabase preKeyDatabase; - private final SignedPreKeyDatabase signedPreKeyDatabase; - private final SessionDatabase sessionDatabase; - private final SearchDatabase searchDatabase; - private final StickerDatabase stickerDatabase; - private final StorageKeyDatabase storageKeyDatabase; - private final RemappedRecordsDatabase remappedRecordsDatabase; - private final MentionDatabase mentionDatabase; - private final PaymentDatabase paymentDatabase; + private final SQLCipherOpenHelper databaseHelper; + private final SmsDatabase sms; + private final MmsDatabase mms; + private final AttachmentDatabase attachments; + private final MediaDatabase media; + private final ThreadDatabase thread; + private final MmsSmsDatabase mmsSmsDatabase; + private final IdentityDatabase identityDatabase; + private final DraftDatabase draftDatabase; + private final PushDatabase pushDatabase; + private final GroupDatabase groupDatabase; + private final RecipientDatabase recipientDatabase; + private final ContactsDatabase contactsDatabase; + private final GroupReceiptDatabase groupReceiptDatabase; + private final OneTimePreKeyDatabase preKeyDatabase; + private final SignedPreKeyDatabase signedPreKeyDatabase; + private final SessionDatabase sessionDatabase; + private final SearchDatabase searchDatabase; + private final StickerDatabase stickerDatabase; + private final UnknownStorageIdDatabase storageIdDatabase ; + private final RemappedRecordsDatabase remappedRecordsDatabase; + private final MentionDatabase mentionDatabase; + private final PaymentDatabase paymentDatabase; public static DatabaseFactory getInstance(Context context) { if (instance == null) { @@ -154,8 +154,8 @@ public class DatabaseFactory { return getInstance(context).stickerDatabase; } - public static StorageKeyDatabase getStorageKeyDatabase(Context context) { - return getInstance(context).storageKeyDatabase; + public static UnknownStorageIdDatabase getUnknownStorageIdDatabase(Context context) { + return getInstance(context).storageIdDatabase; } static RemappedRecordsDatabase getRemappedRecordsDatabase(Context context) { @@ -219,7 +219,7 @@ public class DatabaseFactory { this.sessionDatabase = new SessionDatabase(context, databaseHelper); this.searchDatabase = new SearchDatabase(context, databaseHelper); this.stickerDatabase = new StickerDatabase(context, databaseHelper, attachmentSecret); - this.storageKeyDatabase = new StorageKeyDatabase(context, databaseHelper); + this.storageIdDatabase = new UnknownStorageIdDatabase(context, databaseHelper); this.remappedRecordsDatabase = new RemappedRecordsDatabase(context, databaseHelper); this.mentionDatabase = new MentionDatabase(context, databaseHelper); this.paymentDatabase = new PaymentDatabase(context, databaseHelper); diff --git a/app/src/main/java/org/thoughtcrime/securesms/database/StorageKeyDatabase.java b/app/src/main/java/org/thoughtcrime/securesms/database/UnknownStorageIdDatabase.java similarity index 96% rename from app/src/main/java/org/thoughtcrime/securesms/database/StorageKeyDatabase.java rename to app/src/main/java/org/thoughtcrime/securesms/database/UnknownStorageIdDatabase.java index ad7c812448..54b7a5ae5b 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/database/StorageKeyDatabase.java +++ b/app/src/main/java/org/thoughtcrime/securesms/database/UnknownStorageIdDatabase.java @@ -27,7 +27,7 @@ import java.util.List; * A list of storage keys whose types we do not currently have syncing logic for. We need to * remember that these keys exist so that we don't blast any data away. */ -public class StorageKeyDatabase extends Database { +public class UnknownStorageIdDatabase extends Database { private static final String TABLE_NAME = "storage_key"; private static final String ID = "_id"; @@ -42,11 +42,11 @@ public class StorageKeyDatabase extends Database { "CREATE INDEX IF NOT EXISTS storage_key_type_index ON " + TABLE_NAME + " (" + TYPE + ");" }; - public StorageKeyDatabase(Context context, SQLCipherOpenHelper databaseHelper) { + public UnknownStorageIdDatabase(Context context, SQLCipherOpenHelper databaseHelper) { super(context, databaseHelper); } - public List getAllKeys() { + public List getAllIds() { List keys = new ArrayList<>(); try (Cursor cursor = databaseHelper.getReadableDatabase().query(TABLE_NAME, null, null, null, null, null, null)) { diff --git a/app/src/main/java/org/thoughtcrime/securesms/database/helpers/SQLCipherOpenHelper.java b/app/src/main/java/org/thoughtcrime/securesms/database/helpers/SQLCipherOpenHelper.java index 51cd6c486b..4d6cbb39bf 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/database/helpers/SQLCipherOpenHelper.java +++ b/app/src/main/java/org/thoughtcrime/securesms/database/helpers/SQLCipherOpenHelper.java @@ -43,7 +43,7 @@ import org.thoughtcrime.securesms.database.SignedPreKeyDatabase; import org.thoughtcrime.securesms.database.SmsDatabase; import org.thoughtcrime.securesms.database.SqlCipherDatabaseHook; import org.thoughtcrime.securesms.database.StickerDatabase; -import org.thoughtcrime.securesms.database.StorageKeyDatabase; +import org.thoughtcrime.securesms.database.UnknownStorageIdDatabase; import org.thoughtcrime.securesms.database.ThreadDatabase; import org.thoughtcrime.securesms.dependencies.ApplicationDependencies; import org.thoughtcrime.securesms.groups.GroupId; @@ -201,7 +201,7 @@ public class SQLCipherOpenHelper extends SQLiteOpenHelper implements SignalDatab db.execSQL(SignedPreKeyDatabase.CREATE_TABLE); db.execSQL(SessionDatabase.CREATE_TABLE); db.execSQL(StickerDatabase.CREATE_TABLE); - db.execSQL(StorageKeyDatabase.CREATE_TABLE); + db.execSQL(UnknownStorageIdDatabase.CREATE_TABLE); db.execSQL(MentionDatabase.CREATE_TABLE); db.execSQL(PaymentDatabase.CREATE_TABLE); executeStatements(db, SearchDatabase.CREATE_TABLE); @@ -216,7 +216,7 @@ public class SQLCipherOpenHelper extends SQLiteOpenHelper implements SignalDatab executeStatements(db, GroupDatabase.CREATE_INDEXS); executeStatements(db, GroupReceiptDatabase.CREATE_INDEXES); executeStatements(db, StickerDatabase.CREATE_INDEXES); - executeStatements(db, StorageKeyDatabase.CREATE_INDEXES); + executeStatements(db, UnknownStorageIdDatabase.CREATE_INDEXES); executeStatements(db, MentionDatabase.CREATE_INDEXES); executeStatements(db, PaymentDatabase.CREATE_INDEXES); diff --git a/app/src/main/java/org/thoughtcrime/securesms/jobs/StorageForcePushJob.java b/app/src/main/java/org/thoughtcrime/securesms/jobs/StorageForcePushJob.java index f671aacdf2..130f8050a7 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/jobs/StorageForcePushJob.java +++ b/app/src/main/java/org/thoughtcrime/securesms/jobs/StorageForcePushJob.java @@ -7,7 +7,7 @@ import com.annimon.stream.Stream; import org.signal.core.util.logging.Log; import org.thoughtcrime.securesms.database.DatabaseFactory; import org.thoughtcrime.securesms.database.RecipientDatabase; -import org.thoughtcrime.securesms.database.StorageKeyDatabase; +import org.thoughtcrime.securesms.database.UnknownStorageIdDatabase; import org.thoughtcrime.securesms.dependencies.ApplicationDependencies; import org.thoughtcrime.securesms.jobmanager.Data; import org.thoughtcrime.securesms.jobmanager.Job; @@ -72,10 +72,10 @@ public class StorageForcePushJob extends BaseJob { @Override protected void onRun() throws IOException, RetryLaterException { - StorageKey storageServiceKey = SignalStore.storageServiceValues().getOrCreateStorageKey(); - SignalServiceAccountManager accountManager = ApplicationDependencies.getSignalServiceAccountManager(); - RecipientDatabase recipientDatabase = DatabaseFactory.getRecipientDatabase(context); - StorageKeyDatabase storageKeyDatabase = DatabaseFactory.getStorageKeyDatabase(context); + StorageKey storageServiceKey = SignalStore.storageServiceValues().getOrCreateStorageKey(); + SignalServiceAccountManager accountManager = ApplicationDependencies.getSignalServiceAccountManager(); + RecipientDatabase recipientDatabase = DatabaseFactory.getRecipientDatabase(context); + UnknownStorageIdDatabase storageIdDatabase = DatabaseFactory.getUnknownStorageIdDatabase(context); long currentVersion = accountManager.getStorageManifestVersion(); Map oldContactStorageIds = recipientDatabase.getContactStorageSyncIdsMap(); @@ -99,13 +99,13 @@ public class StorageForcePushJob extends BaseJob { try { if (newVersion > 1) { - Log.i(TAG, String.format(Locale.ENGLISH, "Force-pushing data. Inserting %d keys.", inserts.size())); + Log.i(TAG, String.format(Locale.ENGLISH, "Force-pushing data. Inserting %d IDs.", inserts.size())); if (accountManager.resetStorageRecords(storageServiceKey, manifest, inserts).isPresent()) { Log.w(TAG, "Hit a conflict. Trying again."); throw new RetryLaterException(); } } else { - Log.i(TAG, String.format(Locale.ENGLISH, "First version, normal push. Inserting %d keys.", inserts.size())); + Log.i(TAG, String.format(Locale.ENGLISH, "First version, normal push. Inserting %d IDs.", inserts.size())); if (accountManager.writeStorageRecords(storageServiceKey, manifest, inserts, Collections.emptyList()).isPresent()) { Log.w(TAG, "Hit a conflict. Trying again."); throw new RetryLaterException(); @@ -120,7 +120,7 @@ public class StorageForcePushJob extends BaseJob { TextSecurePreferences.setStorageManifestVersion(context, newVersion); recipientDatabase.applyStorageIdUpdates(newContactStorageIds); recipientDatabase.applyStorageIdUpdates(Collections.singletonMap(Recipient.self().getId(), accountRecord.getId())); - storageKeyDatabase.deleteAll(); + storageIdDatabase.deleteAll(); } @Override 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 70f4814265..90d542bf08 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/jobs/StorageSyncJob.java +++ b/app/src/main/java/org/thoughtcrime/securesms/jobs/StorageSyncJob.java @@ -10,7 +10,7 @@ import org.signal.core.util.logging.Log; import org.thoughtcrime.securesms.database.DatabaseFactory; import org.thoughtcrime.securesms.database.RecipientDatabase; import org.thoughtcrime.securesms.database.RecipientDatabase.RecipientSettings; -import org.thoughtcrime.securesms.database.StorageKeyDatabase; +import org.thoughtcrime.securesms.database.UnknownStorageIdDatabase; import org.thoughtcrime.securesms.dependencies.ApplicationDependencies; import org.thoughtcrime.securesms.groups.GroupId; import org.thoughtcrime.securesms.groups.GroupsV1MigrationUtil; @@ -23,7 +23,7 @@ import org.thoughtcrime.securesms.recipients.RecipientId; import org.thoughtcrime.securesms.storage.GroupV2ExistenceChecker; import org.thoughtcrime.securesms.storage.StaticGroupV2ExistenceChecker; import org.thoughtcrime.securesms.storage.StorageSyncHelper; -import org.thoughtcrime.securesms.storage.StorageSyncHelper.KeyDifferenceResult; +import org.thoughtcrime.securesms.storage.StorageSyncHelper.IdDifferenceResult; import org.thoughtcrime.securesms.storage.StorageSyncHelper.LocalWriteResult; import org.thoughtcrime.securesms.storage.StorageSyncHelper.MergeResult; import org.thoughtcrime.securesms.storage.StorageSyncHelper.WriteOperationResult; @@ -156,7 +156,7 @@ public class StorageSyncJob extends BaseJob { private boolean performSync() throws IOException, RetryLaterException, InvalidKeyException { SignalServiceAccountManager accountManager = ApplicationDependencies.getSignalServiceAccountManager(); RecipientDatabase recipientDatabase = DatabaseFactory.getRecipientDatabase(context); - StorageKeyDatabase storageKeyDatabase = DatabaseFactory.getStorageKeyDatabase(context); + UnknownStorageIdDatabase storageKeyDatabase = DatabaseFactory.getUnknownStorageIdDatabase(context); StorageKey storageServiceKey = SignalStore.storageServiceValues().getOrCreateStorageKey(); boolean needsMultiDeviceSync = false; @@ -171,7 +171,7 @@ public class StorageSyncJob extends BaseJob { Log.i(TAG, "[Remote Newer] Newer manifest version found!"); List allLocalStorageKeys = getAllLocalStorageIds(context, Recipient.self().fresh()); - KeyDifferenceResult keyDifference = StorageSyncHelper.findKeyDifference(remoteManifest.get().getStorageIds(), allLocalStorageKeys); + IdDifferenceResult keyDifference = StorageSyncHelper.findIdDifference(remoteManifest.get().getStorageIds(), allLocalStorageKeys); if (keyDifference.hasTypeMismatches()) { Log.w(TAG, "Found type mismatches in the key sets! Scheduling a force push after this sync completes."); @@ -179,16 +179,16 @@ public class StorageSyncJob extends BaseJob { } if (!keyDifference.isEmpty()) { - Log.i(TAG, "[Remote Newer] There's a difference in keys. Local-only: " + keyDifference.getLocalOnlyKeys().size() + ", Remote-only: " + keyDifference.getRemoteOnlyKeys().size()); + Log.i(TAG, "[Remote Newer] There's a difference in keys. Local-only: " + keyDifference.getLocalOnlyIds().size() + ", Remote-only: " + keyDifference.getRemoteOnlyIds().size()); - List localOnly = buildLocalStorageRecords(context, keyDifference.getLocalOnlyKeys()); - List remoteOnly = accountManager.readStorageRecords(storageServiceKey, keyDifference.getRemoteOnlyKeys()); + List localOnly = buildLocalStorageRecords(context, keyDifference.getLocalOnlyIds()); + List remoteOnly = accountManager.readStorageRecords(storageServiceKey, keyDifference.getRemoteOnlyIds()); GroupV2ExistenceChecker gv2ExistenceChecker = new StaticGroupV2ExistenceChecker(DatabaseFactory.getGroupDatabase(context).getAllGroupV2Ids()); MergeResult mergeResult = StorageSyncHelper.resolveConflict(remoteOnly, localOnly, gv2ExistenceChecker); WriteOperationResult writeOperationResult = StorageSyncHelper.createWriteOperation(remoteManifest.get().getVersion(), allLocalStorageKeys, mergeResult); - if (remoteOnly.size() != keyDifference.getRemoteOnlyKeys().size()) { - Log.w(TAG, "Could not find all remote-only records! Requested: " + keyDifference.getRemoteOnlyKeys().size() + ", Found: " + remoteOnly.size() + ". Scheduling a force push after this sync completes."); + if (remoteOnly.size() != keyDifference.getRemoteOnlyIds().size()) { + Log.w(TAG, "Could not find all remote-only records! Requested: " + keyDifference.getRemoteOnlyIds().size() + ", Found: " + remoteOnly.size() + ". Scheduling a force push after this sync completes."); needsForcePush = true; } @@ -321,13 +321,13 @@ public class StorageSyncJob extends BaseJob { private static @NonNull List getAllLocalStorageIds(@NonNull Context context, @NonNull Recipient self) { return Util.concatenatedList(DatabaseFactory.getRecipientDatabase(context).getContactStorageSyncIds(), Collections.singletonList(StorageId.forAccount(self.getStorageServiceId())), - DatabaseFactory.getStorageKeyDatabase(context).getAllKeys()); + DatabaseFactory.getUnknownStorageIdDatabase(context).getAllIds()); } private static @NonNull List buildLocalStorageRecords(@NonNull Context context, @NonNull List ids) { Recipient self = Recipient.self().fresh(); RecipientDatabase recipientDatabase = DatabaseFactory.getRecipientDatabase(context); - StorageKeyDatabase storageKeyDatabase = DatabaseFactory.getStorageKeyDatabase(context); + UnknownStorageIdDatabase storageKeyDatabase = DatabaseFactory.getUnknownStorageIdDatabase(context); List records = new ArrayList<>(ids.size()); 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 98fa561206..181e5c9dc7 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/jobs/StorageSyncJobV2.java +++ b/app/src/main/java/org/thoughtcrime/securesms/jobs/StorageSyncJobV2.java @@ -12,7 +12,7 @@ import org.signal.core.util.logging.Log; import org.thoughtcrime.securesms.database.DatabaseFactory; import org.thoughtcrime.securesms.database.RecipientDatabase; import org.thoughtcrime.securesms.database.RecipientDatabase.RecipientSettings; -import org.thoughtcrime.securesms.database.StorageKeyDatabase; +import org.thoughtcrime.securesms.database.UnknownStorageIdDatabase; import org.thoughtcrime.securesms.dependencies.ApplicationDependencies; import org.thoughtcrime.securesms.jobmanager.Data; import org.thoughtcrime.securesms.jobmanager.Job; @@ -25,10 +25,9 @@ import org.thoughtcrime.securesms.storage.AccountRecordProcessor; import org.thoughtcrime.securesms.storage.ContactRecordProcessor; import org.thoughtcrime.securesms.storage.GroupV1RecordProcessor; import org.thoughtcrime.securesms.storage.GroupV2RecordProcessor; -import org.thoughtcrime.securesms.storage.StorageRecordProcessor; import org.thoughtcrime.securesms.storage.StorageRecordUpdate; import org.thoughtcrime.securesms.storage.StorageSyncHelper; -import org.thoughtcrime.securesms.storage.StorageSyncHelper.KeyDifferenceResult; +import org.thoughtcrime.securesms.storage.StorageSyncHelper.IdDifferenceResult; import org.thoughtcrime.securesms.storage.StorageSyncHelper.LocalWriteResult; import org.thoughtcrime.securesms.storage.StorageSyncHelper.WriteOperationResult; import org.thoughtcrime.securesms.storage.StorageSyncModels; @@ -54,7 +53,6 @@ import org.whispersystems.signalservice.api.storage.StorageKey; import org.whispersystems.signalservice.internal.storage.protos.ManifestRecord; import java.io.IOException; -import java.nio.ByteBuffer; import java.util.ArrayList; import java.util.Arrays; import java.util.Collection; @@ -85,7 +83,7 @@ import java.util.concurrent.TimeUnit; * fall out of sync if the network request fails. However, because of how the sync works, as long * as we don't update our local manifest version until after the network request succeeds, it * should all sort itself out in the retry. Because if our network request failed, then we - * wouldn't have written all of the new keys, and we'll still see a bunch of remote-only keys that + * wouldn't have written all of the new IDs, and we'll still see a bunch of remote-only IDs that * we'll merge with local data to generate another equally-valid set of remote changes. * * @@ -211,7 +209,7 @@ public class StorageSyncJobV2 extends BaseJob { Recipient self = Recipient.self(); SignalServiceAccountManager accountManager = ApplicationDependencies.getSignalServiceAccountManager(); RecipientDatabase recipientDatabase = DatabaseFactory.getRecipientDatabase(context); - StorageKeyDatabase storageKeyDatabase = DatabaseFactory.getStorageKeyDatabase(context); + UnknownStorageIdDatabase storageIdDatabase = DatabaseFactory.getUnknownStorageIdDatabase(context); StorageKey storageServiceKey = SignalStore.storageServiceValues().getOrCreateStorageKey(); boolean needsMultiDeviceSync = false; @@ -227,25 +225,25 @@ public class StorageSyncJobV2 extends BaseJob { if (remoteManifest.isPresent() && remoteManifestVersion > localManifestVersion) { Log.i(TAG, "[Remote Sync] Newer manifest version found!"); - List localStorageIdsBeforeMerge = getAllLocalStorageIds(context, Recipient.self().fresh()); - KeyDifferenceResult keyDifference = StorageSyncHelper.findKeyDifference(remoteManifest.get().getStorageIds(), localStorageIdsBeforeMerge); + List localStorageIdsBeforeMerge = getAllLocalStorageIds(context, Recipient.self().fresh()); + IdDifferenceResult idDifference = StorageSyncHelper.findIdDifference(remoteManifest.get().getStorageIds(), localStorageIdsBeforeMerge); - if (keyDifference.hasTypeMismatches()) { - Log.w(TAG, "[Remote Sync] Found type mismatches in the key sets! Scheduling a force push after this sync completes."); + if (idDifference.hasTypeMismatches()) { + Log.w(TAG, "[Remote Sync] Found type mismatches in the ID sets! Scheduling a force push after this sync completes."); needsForcePush = true; } - Log.i(TAG, "[Remote Sync] Pre-Merge Key Difference :: " + keyDifference); + Log.i(TAG, "[Remote Sync] Pre-Merge ID Difference :: " + idDifference); - if (!keyDifference.isEmpty()) { + if (!idDifference.isEmpty()) { Log.i(TAG, "[Remote Sync] Retrieving records for key difference."); - List remoteOnly = accountManager.readStorageRecords(storageServiceKey, keyDifference.getRemoteOnlyKeys()); + List remoteOnly = accountManager.readStorageRecords(storageServiceKey, idDifference.getRemoteOnlyIds()); stopwatch.split("remote-records"); - if (remoteOnly.size() != keyDifference.getRemoteOnlyKeys().size()) { - Log.w(TAG, "[Remote Sync] Could not find all remote-only records! Requested: " + keyDifference.getRemoteOnlyKeys().size() + ", Found: " + remoteOnly.size() + ". Scheduling a force push after this sync completes."); + if (remoteOnly.size() != idDifference.getRemoteOnlyIds().size()) { + Log.w(TAG, "[Remote Sync] Could not find all remote-only records! Requested: " + idDifference.getRemoteOnlyIds().size() + ", Found: " + remoteOnly.size() + ". Scheduling a force push after this sync completes."); needsForcePush = true; } @@ -281,24 +279,24 @@ public class StorageSyncJobV2 extends BaseJob { new AccountRecordProcessor(context, self).process(remoteAccount, StorageSyncHelper.KEY_GENERATOR); List unknownInserts = remoteUnknown; - List unknownDeletes = Stream.of(keyDifference.getLocalOnlyKeys()).filter(StorageId::isUnknown).toList(); + List unknownDeletes = Stream.of(idDifference.getLocalOnlyIds()).filter(StorageId::isUnknown).toList(); - storageKeyDatabase.insert(unknownInserts); - storageKeyDatabase.delete(unknownDeletes); + storageIdDatabase.insert(unknownInserts); + storageIdDatabase.delete(unknownDeletes); Log.i(TAG, "[Remote Sync] Unknowns :: " + unknownInserts.size() + " inserts, " + unknownDeletes.size() + " deletes"); List localStorageIdsAfterMerge = getAllLocalStorageIds(context, Recipient.self().fresh()); - Set localKeysAdded = SetUtil.difference(localStorageIdsAfterMerge, localStorageIdsBeforeMerge); - Set localKeysRemoved = SetUtil.difference(localStorageIdsBeforeMerge, localStorageIdsAfterMerge); + Set localIdsAdded = SetUtil.difference(localStorageIdsAfterMerge, localStorageIdsBeforeMerge); + Set localIdsRemoved = SetUtil.difference(localStorageIdsBeforeMerge, localStorageIdsAfterMerge); - Log.i(TAG, "[Remote Sync] Local ID Changes :: " + localKeysAdded.size() + " inserts, " + localKeysRemoved.size() + " deletes"); + Log.i(TAG, "[Remote Sync] Local ID Changes :: " + localIdsAdded.size() + " inserts, " + localIdsRemoved.size() + " deletes"); - KeyDifferenceResult postMergeKeyDifference = StorageSyncHelper.findKeyDifference(remoteManifest.get().getStorageIds(), localStorageIdsAfterMerge); - List remoteInserts = buildLocalStorageRecords(context, self, postMergeKeyDifference.getLocalOnlyKeys()); - List remoteDeletes = Stream.of(postMergeKeyDifference.getRemoteOnlyKeys()).map(StorageId::getRaw).toList(); + IdDifferenceResult postMergeIdDifference = StorageSyncHelper.findIdDifference(remoteManifest.get().getStorageIds(), localStorageIdsAfterMerge); + List remoteInserts = buildLocalStorageRecords(context, self, postMergeIdDifference.getLocalOnlyIds()); + List remoteDeletes = Stream.of(postMergeIdDifference.getRemoteOnlyIds()).map(StorageId::getRaw).toList(); - Log.i(TAG, "[Remote Sync] Post-Merge Key Difference :: " + postMergeKeyDifference); + Log.i(TAG, "[Remote Sync] Post-Merge ID Difference :: " + postMergeIdDifference); mergeWriteOperation = new WriteOperationResult(new SignalStorageManifest(remoteManifestVersion + 1, localStorageIdsAfterMerge), remoteInserts, @@ -339,7 +337,7 @@ public class StorageSyncJobV2 extends BaseJob { Log.i(TAG, "[Remote Sync] Updating local manifest version to: " + remoteManifestVersion); TextSecurePreferences.setStorageManifestVersion(context, remoteManifestVersion); } else { - Log.i(TAG, "[Remote Sync] Remote version was newer, there were no remote-only keys."); + Log.i(TAG, "[Remote Sync] Remote version was newer, there were no remote-only IDs."); Log.i(TAG, "[Remote Sync] Updating local manifest version to: " + remoteManifest.get().getVersion()); TextSecurePreferences.setStorageManifestVersion(context, remoteManifest.get().getVersion()); } @@ -350,14 +348,14 @@ public class StorageSyncJobV2 extends BaseJob { localManifestVersion = TextSecurePreferences.getStorageManifestVersion(context); - List allLocalStorageKeys = getAllLocalStorageIds(context, self); + List allLocalStorageIds = getAllLocalStorageIds(context, self); List pendingUpdates = recipientDatabase.getPendingRecipientSyncUpdates(); List pendingInsertions = recipientDatabase.getPendingRecipientSyncInsertions(); List pendingDeletions = recipientDatabase.getPendingRecipientSyncDeletions(); Optional pendingAccountInsert = StorageSyncHelper.getPendingAccountSyncInsert(context, self); Optional pendingAccountUpdate = StorageSyncHelper.getPendingAccountSyncUpdate(context, self); Optional localWriteResult = StorageSyncHelper.buildStorageUpdatesForLocal(localManifestVersion, - allLocalStorageKeys, + allLocalStorageIds, pendingUpdates, pendingInsertions, pendingDeletions, @@ -420,7 +418,7 @@ public class StorageSyncJobV2 extends BaseJob { private static @NonNull List getAllLocalStorageIds(@NonNull Context context, @NonNull Recipient self) { return Util.concatenatedList(DatabaseFactory.getRecipientDatabase(context).getContactStorageSyncIds(), Collections.singletonList(StorageId.forAccount(self.getStorageServiceId())), - DatabaseFactory.getStorageKeyDatabase(context).getAllKeys()); + DatabaseFactory.getUnknownStorageIdDatabase(context).getAllIds()); } private static @NonNull List buildLocalStorageRecords(@NonNull Context context, @NonNull Recipient self, @NonNull Collection ids) { @@ -428,8 +426,8 @@ public class StorageSyncJobV2 extends BaseJob { return Collections.emptyList(); } - RecipientDatabase recipientDatabase = DatabaseFactory.getRecipientDatabase(context); - StorageKeyDatabase storageKeyDatabase = DatabaseFactory.getStorageKeyDatabase(context); + RecipientDatabase recipientDatabase = DatabaseFactory.getRecipientDatabase(context); + UnknownStorageIdDatabase storageIdDatabase = DatabaseFactory.getUnknownStorageIdDatabase(context); List records = new ArrayList<>(ids.size()); @@ -456,7 +454,7 @@ public class StorageSyncJobV2 extends BaseJob { records.add(StorageSyncHelper.buildAccountRecord(context, self)); break; default: - SignalStorageRecord unknown = storageKeyDatabase.getById(id.getRaw()); + SignalStorageRecord unknown = storageIdDatabase.getById(id.getRaw()); if (unknown != null) { records.add(unknown); } else { diff --git a/app/src/main/java/org/thoughtcrime/securesms/storage/StorageSyncHelper.java b/app/src/main/java/org/thoughtcrime/securesms/storage/StorageSyncHelper.java index 6cb19f1fda..ad5392ad6a 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/storage/StorageSyncHelper.java +++ b/app/src/main/java/org/thoughtcrime/securesms/storage/StorageSyncHelper.java @@ -205,19 +205,19 @@ public final class StorageSyncHelper { * Given a list of all the local and remote keys you know about, this will return a result telling * you which keys are exclusively remote and which are exclusively local. * - * @param remoteKeys All remote keys available. - * @param localKeys All local keys available. + * @param remoteIds All remote keys available. + * @param localIds All local keys available. * * @return An object describing which keys are exclusive to the remote data set and which keys are * exclusive to the local data set. */ - public static @NonNull KeyDifferenceResult findKeyDifference(@NonNull Collection remoteKeys, - @NonNull Collection localKeys) + public static @NonNull IdDifferenceResult findIdDifference(@NonNull Collection remoteIds, + @NonNull Collection localIds) { - Map remoteByRawId = Stream.of(remoteKeys).collect(Collectors.toMap(id -> Base64.encodeBytes(id.getRaw()), id -> id)); - Map localByRawId = Stream.of(localKeys).collect(Collectors.toMap(id -> Base64.encodeBytes(id.getRaw()), id -> id)); + Map remoteByRawId = Stream.of(remoteIds).collect(Collectors.toMap(id -> Base64.encodeBytes(id.getRaw()), id -> id)); + Map localByRawId = Stream.of(localIds).collect(Collectors.toMap(id -> Base64.encodeBytes(id.getRaw()), id -> id)); - boolean hasTypeMismatch = remoteByRawId.size() != remoteKeys.size() || localByRawId.size() != localKeys.size(); + boolean hasTypeMismatch = remoteByRawId.size() != remoteIds.size() || localByRawId.size() != localIds.size(); Set remoteOnlyRawIds = SetUtil.difference(remoteByRawId.keySet(), localByRawId.keySet()); Set localOnlyRawIds = SetUtil.difference(localByRawId.keySet(), remoteByRawId.keySet()); @@ -238,7 +238,7 @@ public final class StorageSyncHelper { List remoteOnlyKeys = Stream.of(remoteOnlyRawIds).map(remoteByRawId::get).toList(); List localOnlyKeys = Stream.of(localOnlyRawIds).map(localByRawId::get).toList(); - return new KeyDifferenceResult(remoteOnlyKeys, localOnlyKeys, hasTypeMismatch); + return new IdDifferenceResult(remoteOnlyKeys, localOnlyKeys, hasTypeMismatch); } /** @@ -483,26 +483,26 @@ public final class StorageSyncHelper { } } - public static final class KeyDifferenceResult { - private final List remoteOnlyKeys; - private final List localOnlyKeys; + public static final class IdDifferenceResult { + private final List remoteOnlyIds; + private final List localOnlyIds; private final boolean hasTypeMismatches; - private KeyDifferenceResult(@NonNull List remoteOnlyKeys, - @NonNull List localOnlyKeys, - boolean hasTypeMismatches) + private IdDifferenceResult(@NonNull List remoteOnlyIds, + @NonNull List localOnlyIds, + boolean hasTypeMismatches) { - this.remoteOnlyKeys = remoteOnlyKeys; - this.localOnlyKeys = localOnlyKeys; + this.remoteOnlyIds = remoteOnlyIds; + this.localOnlyIds = localOnlyIds; this.hasTypeMismatches = hasTypeMismatches; } - public @NonNull List getRemoteOnlyKeys() { - return remoteOnlyKeys; + public @NonNull List getRemoteOnlyIds() { + return remoteOnlyIds; } - public @NonNull List getLocalOnlyKeys() { - return localOnlyKeys; + public @NonNull List getLocalOnlyIds() { + return localOnlyIds; } /** @@ -514,12 +514,12 @@ public final class StorageSyncHelper { } public boolean isEmpty() { - return remoteOnlyKeys.isEmpty() && localOnlyKeys.isEmpty(); + return remoteOnlyIds.isEmpty() && localOnlyIds.isEmpty(); } @Override public @NonNull String toString() { - return "remoteOnly: " + remoteOnlyKeys.size() + ", localOnly: " + localOnlyKeys.size() + ", hasTypeMismatches: " + hasTypeMismatches; + return "remoteOnly: " + remoteOnlyIds.size() + ", localOnly: " + localOnlyIds.size() + ", hasTypeMismatches: " + hasTypeMismatches; } } diff --git a/app/src/test/java/org/thoughtcrime/securesms/storage/StorageSyncHelperTest.java b/app/src/test/java/org/thoughtcrime/securesms/storage/StorageSyncHelperTest.java index 6077d668de..ff5a207d0b 100644 --- a/app/src/test/java/org/thoughtcrime/securesms/storage/StorageSyncHelperTest.java +++ b/app/src/test/java/org/thoughtcrime/securesms/storage/StorageSyncHelperTest.java @@ -14,7 +14,7 @@ import org.powermock.modules.junit4.PowerMockRunner; import org.powermock.modules.junit4.PowerMockRunnerDelegate; import org.signal.core.util.logging.Log; import org.thoughtcrime.securesms.recipients.Recipient; -import org.thoughtcrime.securesms.storage.StorageSyncHelper.KeyDifferenceResult; +import org.thoughtcrime.securesms.storage.StorageSyncHelper.IdDifferenceResult; import org.thoughtcrime.securesms.storage.StorageSyncHelper.MergeResult; import org.thoughtcrime.securesms.util.FeatureFlags; import org.thoughtcrime.securesms.util.Util; @@ -90,60 +90,60 @@ public final class StorageSyncHelperTest { } @Test - public void findKeyDifference_allOverlap() { - KeyDifferenceResult result = StorageSyncHelper.findKeyDifference(keyListOf(1, 2, 3), keyListOf(1, 2, 3)); - assertTrue(result.getLocalOnlyKeys().isEmpty()); - assertTrue(result.getRemoteOnlyKeys().isEmpty()); + public void findIdDifference_allOverlap() { + IdDifferenceResult result = StorageSyncHelper.findIdDifference(keyListOf(1, 2, 3), keyListOf(1, 2, 3)); + assertTrue(result.getLocalOnlyIds().isEmpty()); + assertTrue(result.getRemoteOnlyIds().isEmpty()); assertFalse(result.hasTypeMismatches()); } @Test - public void findKeyDifference_noOverlap() { - KeyDifferenceResult result = StorageSyncHelper.findKeyDifference(keyListOf(1, 2, 3), keyListOf(4, 5, 6)); - assertContentsEqual(keyListOf(1, 2, 3), result.getRemoteOnlyKeys()); - assertContentsEqual(keyListOf(4, 5, 6), result.getLocalOnlyKeys()); + public void findIdDifference_noOverlap() { + IdDifferenceResult result = StorageSyncHelper.findIdDifference(keyListOf(1, 2, 3), keyListOf(4, 5, 6)); + assertContentsEqual(keyListOf(1, 2, 3), result.getRemoteOnlyIds()); + assertContentsEqual(keyListOf(4, 5, 6), result.getLocalOnlyIds()); assertFalse(result.hasTypeMismatches()); } @Test - public void findKeyDifference_someOverlap() { - KeyDifferenceResult result = StorageSyncHelper.findKeyDifference(keyListOf(1, 2, 3), keyListOf(2, 3, 4)); - assertContentsEqual(keyListOf(1), result.getRemoteOnlyKeys()); - assertContentsEqual(keyListOf(4), result.getLocalOnlyKeys()); + public void findIdDifference_someOverlap() { + IdDifferenceResult result = StorageSyncHelper.findIdDifference(keyListOf(1, 2, 3), keyListOf(2, 3, 4)); + assertContentsEqual(keyListOf(1), result.getRemoteOnlyIds()); + assertContentsEqual(keyListOf(4), result.getLocalOnlyIds()); assertFalse(result.hasTypeMismatches()); } @Test - public void findKeyDifference_typeMismatch_allOverlap() { - KeyDifferenceResult result = StorageSyncHelper.findKeyDifference(keyListOf(new HashMap() {{ - put(100, 1); - put(200, 2); - }}), - keyListOf(new HashMap() {{ - put(100, 1); - put(200, 1); - }})); + public void findIdDifference_typeMismatch_allOverlap() { + IdDifferenceResult result = StorageSyncHelper.findIdDifference(keyListOf(new HashMap() {{ + put(100, 1); + put(200, 2); + }}), + keyListOf(new HashMap() {{ + put(100, 1); + put(200, 1); + }})); - assertTrue(result.getLocalOnlyKeys().isEmpty()); - assertTrue(result.getRemoteOnlyKeys().isEmpty()); + assertTrue(result.getLocalOnlyIds().isEmpty()); + assertTrue(result.getRemoteOnlyIds().isEmpty()); assertTrue(result.hasTypeMismatches()); } @Test - public void findKeyDifference_typeMismatch_someOverlap() { - KeyDifferenceResult result = StorageSyncHelper.findKeyDifference(keyListOf(new HashMap() {{ - put(100, 1); - put(200, 2); - put(300, 1); - }}), - keyListOf(new HashMap() {{ - put(100, 1); - put(200, 1); - put(400, 1); - }})); + public void findIdDifference_typeMismatch_someOverlap() { + IdDifferenceResult result = StorageSyncHelper.findIdDifference(keyListOf(new HashMap() {{ + put(100, 1); + put(200, 2); + put(300, 1); + }}), + keyListOf(new HashMap() {{ + put(100, 1); + put(200, 1); + put(400, 1); + }})); - assertContentsEqual(Arrays.asList(StorageId.forType(byteArray(300), 1)), result.getRemoteOnlyKeys()); - assertContentsEqual(Arrays.asList(StorageId.forType(byteArray(400), 1)), result.getLocalOnlyKeys()); + assertContentsEqual(Arrays.asList(StorageId.forType(byteArray(300), 1)), result.getRemoteOnlyIds()); + assertContentsEqual(Arrays.asList(StorageId.forType(byteArray(400), 1)), result.getLocalOnlyIds()); assertTrue(result.hasTypeMismatches()); }