Rename 'key' to 'id' where appropriate for storage service.
This commit is contained in:
parent
9c428f6db7
commit
35ab2f6704
8 changed files with 140 additions and 142 deletions
|
@ -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);
|
||||
|
|
|
@ -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)) {
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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());
|
||||
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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());
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue