Rename 'key' to 'id' where appropriate for storage service.

This commit is contained in:
Greyson Parrelli 2021-04-17 10:14:59 -04:00
parent 9c428f6db7
commit 35ab2f6704
8 changed files with 140 additions and 142 deletions

View file

@ -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);

View file

@ -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<StorageId> getAllKeys() {
public List<StorageId> getAllIds() {
List<StorageId> keys = new ArrayList<>();
try (Cursor cursor = databaseHelper.getReadableDatabase().query(TABLE_NAME, null, null, null, null, null, null)) {

View file

@ -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);

View file

@ -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<RecipientId, StorageId> 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

View file

@ -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<StorageId> 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<SignalStorageRecord> localOnly = buildLocalStorageRecords(context, keyDifference.getLocalOnlyKeys());
List<SignalStorageRecord> remoteOnly = accountManager.readStorageRecords(storageServiceKey, keyDifference.getRemoteOnlyKeys());
List<SignalStorageRecord> localOnly = buildLocalStorageRecords(context, keyDifference.getLocalOnlyIds());
List<SignalStorageRecord> 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<StorageId> 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<SignalStorageRecord> buildLocalStorageRecords(@NonNull Context context, @NonNull List<StorageId> ids) {
Recipient self = Recipient.self().fresh();
RecipientDatabase recipientDatabase = DatabaseFactory.getRecipientDatabase(context);
StorageKeyDatabase storageKeyDatabase = DatabaseFactory.getStorageKeyDatabase(context);
UnknownStorageIdDatabase storageKeyDatabase = DatabaseFactory.getUnknownStorageIdDatabase(context);
List<SignalStorageRecord> records = new ArrayList<>(ids.size());

View file

@ -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<StorageId> localStorageIdsBeforeMerge = getAllLocalStorageIds(context, Recipient.self().fresh());
KeyDifferenceResult keyDifference = StorageSyncHelper.findKeyDifference(remoteManifest.get().getStorageIds(), localStorageIdsBeforeMerge);
List<StorageId> 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<SignalStorageRecord> remoteOnly = accountManager.readStorageRecords(storageServiceKey, keyDifference.getRemoteOnlyKeys());
List<SignalStorageRecord> 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<SignalStorageRecord> unknownInserts = remoteUnknown;
List<StorageId> unknownDeletes = Stream.of(keyDifference.getLocalOnlyKeys()).filter(StorageId::isUnknown).toList();
List<StorageId> 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<StorageId> localStorageIdsAfterMerge = getAllLocalStorageIds(context, Recipient.self().fresh());
Set<StorageId> localKeysAdded = SetUtil.difference(localStorageIdsAfterMerge, localStorageIdsBeforeMerge);
Set<StorageId> localKeysRemoved = SetUtil.difference(localStorageIdsBeforeMerge, localStorageIdsAfterMerge);
Set<StorageId> localIdsAdded = SetUtil.difference(localStorageIdsAfterMerge, localStorageIdsBeforeMerge);
Set<StorageId> 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<SignalStorageRecord> remoteInserts = buildLocalStorageRecords(context, self, postMergeKeyDifference.getLocalOnlyKeys());
List<byte[]> remoteDeletes = Stream.of(postMergeKeyDifference.getRemoteOnlyKeys()).map(StorageId::getRaw).toList();
IdDifferenceResult postMergeIdDifference = StorageSyncHelper.findIdDifference(remoteManifest.get().getStorageIds(), localStorageIdsAfterMerge);
List<SignalStorageRecord> remoteInserts = buildLocalStorageRecords(context, self, postMergeIdDifference.getLocalOnlyIds());
List<byte[]> 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<StorageId> allLocalStorageKeys = getAllLocalStorageIds(context, self);
List<StorageId> allLocalStorageIds = getAllLocalStorageIds(context, self);
List<RecipientSettings> pendingUpdates = recipientDatabase.getPendingRecipientSyncUpdates();
List<RecipientSettings> pendingInsertions = recipientDatabase.getPendingRecipientSyncInsertions();
List<RecipientSettings> pendingDeletions = recipientDatabase.getPendingRecipientSyncDeletions();
Optional<SignalAccountRecord> pendingAccountInsert = StorageSyncHelper.getPendingAccountSyncInsert(context, self);
Optional<SignalAccountRecord> pendingAccountUpdate = StorageSyncHelper.getPendingAccountSyncUpdate(context, self);
Optional<LocalWriteResult> localWriteResult = StorageSyncHelper.buildStorageUpdatesForLocal(localManifestVersion,
allLocalStorageKeys,
allLocalStorageIds,
pendingUpdates,
pendingInsertions,
pendingDeletions,
@ -420,7 +418,7 @@ public class StorageSyncJobV2 extends BaseJob {
private static @NonNull List<StorageId> 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<SignalStorageRecord> buildLocalStorageRecords(@NonNull Context context, @NonNull Recipient self, @NonNull Collection<StorageId> 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<SignalStorageRecord> 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 {

View file

@ -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<StorageId> remoteKeys,
@NonNull Collection<StorageId> localKeys)
public static @NonNull IdDifferenceResult findIdDifference(@NonNull Collection<StorageId> remoteIds,
@NonNull Collection<StorageId> localIds)
{
Map<String, StorageId> remoteByRawId = Stream.of(remoteKeys).collect(Collectors.toMap(id -> Base64.encodeBytes(id.getRaw()), id -> id));
Map<String, StorageId> localByRawId = Stream.of(localKeys).collect(Collectors.toMap(id -> Base64.encodeBytes(id.getRaw()), id -> id));
Map<String, StorageId> remoteByRawId = Stream.of(remoteIds).collect(Collectors.toMap(id -> Base64.encodeBytes(id.getRaw()), id -> id));
Map<String, StorageId> 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<String> remoteOnlyRawIds = SetUtil.difference(remoteByRawId.keySet(), localByRawId.keySet());
Set<String> localOnlyRawIds = SetUtil.difference(localByRawId.keySet(), remoteByRawId.keySet());
@ -238,7 +238,7 @@ public final class StorageSyncHelper {
List<StorageId> remoteOnlyKeys = Stream.of(remoteOnlyRawIds).map(remoteByRawId::get).toList();
List<StorageId> 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<StorageId> remoteOnlyKeys;
private final List<StorageId> localOnlyKeys;
public static final class IdDifferenceResult {
private final List<StorageId> remoteOnlyIds;
private final List<StorageId> localOnlyIds;
private final boolean hasTypeMismatches;
private KeyDifferenceResult(@NonNull List<StorageId> remoteOnlyKeys,
@NonNull List<StorageId> localOnlyKeys,
boolean hasTypeMismatches)
private IdDifferenceResult(@NonNull List<StorageId> remoteOnlyIds,
@NonNull List<StorageId> localOnlyIds,
boolean hasTypeMismatches)
{
this.remoteOnlyKeys = remoteOnlyKeys;
this.localOnlyKeys = localOnlyKeys;
this.remoteOnlyIds = remoteOnlyIds;
this.localOnlyIds = localOnlyIds;
this.hasTypeMismatches = hasTypeMismatches;
}
public @NonNull List<StorageId> getRemoteOnlyKeys() {
return remoteOnlyKeys;
public @NonNull List<StorageId> getRemoteOnlyIds() {
return remoteOnlyIds;
}
public @NonNull List<StorageId> getLocalOnlyKeys() {
return localOnlyKeys;
public @NonNull List<StorageId> 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;
}
}

View file

@ -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<Integer, Integer>() {{
put(100, 1);
put(200, 2);
}}),
keyListOf(new HashMap<Integer, Integer>() {{
put(100, 1);
put(200, 1);
}}));
public void findIdDifference_typeMismatch_allOverlap() {
IdDifferenceResult result = StorageSyncHelper.findIdDifference(keyListOf(new HashMap<Integer, Integer>() {{
put(100, 1);
put(200, 2);
}}),
keyListOf(new HashMap<Integer, Integer>() {{
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<Integer, Integer>() {{
put(100, 1);
put(200, 2);
put(300, 1);
}}),
keyListOf(new HashMap<Integer, Integer>() {{
put(100, 1);
put(200, 1);
put(400, 1);
}}));
public void findIdDifference_typeMismatch_someOverlap() {
IdDifferenceResult result = StorageSyncHelper.findIdDifference(keyListOf(new HashMap<Integer, Integer>() {{
put(100, 1);
put(200, 2);
put(300, 1);
}}),
keyListOf(new HashMap<Integer, Integer>() {{
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());
}