@Test public void createWriteOperation_generic() { List<StorageId> localKeys = Arrays.asList(contactKey(1), contactKey(2), contactKey(3), contactKey(4), groupV1Key(100), groupV2Key(200)); SignalContactRecord insert1 = contact(6, UUID_A, E164_A, "a"); SignalContactRecord old1 = contact(1, UUID_B, E164_B, "b"); SignalContactRecord new1 = contact(5, UUID_B, E164_B, "z"); SignalContactRecord insert2 = contact(7, UUID_C, E164_C, "c"); SignalContactRecord old2 = contact(2, UUID_D, E164_D, "d"); SignalContactRecord new2 = contact(8, UUID_D, E164_D, "z2"); SignalGroupV1Record insert3 = groupV1(9, 1, true, true); SignalGroupV1Record old3 = groupV1(100, 1, true, true); SignalGroupV1Record new3 = groupV1(10, 1, false, true); SignalGroupV2Record insert4 = groupV2(19, 2, true, true); SignalGroupV2Record old4 = groupV2(200, 2, true, true); SignalGroupV2Record new4 = groupV2(20, 2, false, true); SignalStorageRecord unknownInsert = unknown(11); SignalStorageRecord unknownDelete = unknown(12); StorageSyncHelper.WriteOperationResult result = StorageSyncHelper.createWriteOperation(1, localKeys, new MergeResult(setOf(insert2), setOf(update(old2, new2)), setOf(insert3), setOf(update(old3, new3)), setOf(insert4), setOf(update(old4, new4)), setOf(unknownInsert), setOf(unknownDelete), Optional.absent(), recordSetOf(insert1, insert3, insert4), setOf(recordUpdate(old1, new1), recordUpdate(old3, new3), recordUpdate(old4, new4)), setOf())); assertEquals(2, result.getManifest().getVersion()); assertContentsEqual(Arrays.asList(contactKey(3), contactKey(4), contactKey(5), contactKey(6), contactKey(7), contactKey(8), groupV1Key(9), groupV1Key(10), groupV2Key(19), groupV2Key(20), unknownKey(11)), result.getManifest().getStorageIds()); assertEquals(recordSetOf(insert1, new1, insert3, new3, insert4, new4), new HashSet<>(result.getInserts())); assertByteListEquals(byteListOf(1, 100, 200), result.getDeletes()); }
public static @NonNull WriteOperationResult createWriteOperation(long currentManifestVersion, @NonNull List<StorageId> currentLocalStorageKeys, @NonNull MergeResult mergeResult) { List<SignalStorageRecord> inserts = new ArrayList<>(); inserts.addAll(mergeResult.getRemoteInserts()); inserts.addAll(Stream.of(mergeResult.getRemoteUpdates()).map(RecordUpdate::getNew).toList()); List<StorageId> deletes = new ArrayList<>(); deletes.addAll(Stream.of(mergeResult.getRemoteDeletes()).map(SignalRecord::getId).toList()); deletes.addAll(Stream.of(mergeResult.getRemoteUpdates()).map(RecordUpdate::getOld).map(SignalStorageRecord::getId).toList()); Set<StorageId> completeKeys = new HashSet<>(currentLocalStorageKeys); completeKeys.addAll(Stream.of(mergeResult.getAllNewRecords()).map(SignalRecord::getId).toList()); completeKeys.removeAll(Stream.of(mergeResult.getAllRemovedRecords()).map(SignalRecord::getId).toList()); completeKeys.addAll(Stream.of(inserts).map(SignalStorageRecord::getId).toList()); completeKeys.removeAll(deletes); SignalStorageManifest manifest = new SignalStorageManifest(currentManifestVersion + 1, new ArrayList<>(completeKeys)); return new WriteOperationResult(manifest, inserts, Stream.of(deletes).map(StorageId::getRaw).toList()); }
StorageSyncHelper { public static @NonNull WriteOperationResult createWriteOperation(long currentManifestVersion, @NonNull List<StorageId> currentLocalStorageKeys, @NonNull MergeResult mergeResult) { List<SignalStorageRecord> inserts = new ArrayList<>(); inserts.addAll(mergeResult.getRemoteInserts()); inserts.addAll(Stream.of(mergeResult.getRemoteUpdates()).map(RecordUpdate::getNew).toList()); List<StorageId> deletes = new ArrayList<>(); deletes.addAll(Stream.of(mergeResult.getRemoteDeletes()).map(SignalRecord::getId).toList()); deletes.addAll(Stream.of(mergeResult.getRemoteUpdates()).map(RecordUpdate::getOld).map(SignalStorageRecord::getId).toList()); Set<StorageId> completeKeys = new HashSet<>(currentLocalStorageKeys); completeKeys.addAll(Stream.of(mergeResult.getAllNewRecords()).map(SignalRecord::getId).toList()); completeKeys.removeAll(Stream.of(mergeResult.getAllRemovedRecords()).map(SignalRecord::getId).toList()); completeKeys.addAll(Stream.of(inserts).map(SignalStorageRecord::getId).toList()); completeKeys.removeAll(deletes); SignalStorageManifest manifest = new SignalStorageManifest(currentManifestVersion + 1, new ArrayList<>(completeKeys)); return new WriteOperationResult(manifest, inserts, Stream.of(deletes).map(StorageId::getRaw).toList()); } }
StorageSyncHelper { public static @NonNull WriteOperationResult createWriteOperation(long currentManifestVersion, @NonNull List<StorageId> currentLocalStorageKeys, @NonNull MergeResult mergeResult) { List<SignalStorageRecord> inserts = new ArrayList<>(); inserts.addAll(mergeResult.getRemoteInserts()); inserts.addAll(Stream.of(mergeResult.getRemoteUpdates()).map(RecordUpdate::getNew).toList()); List<StorageId> deletes = new ArrayList<>(); deletes.addAll(Stream.of(mergeResult.getRemoteDeletes()).map(SignalRecord::getId).toList()); deletes.addAll(Stream.of(mergeResult.getRemoteUpdates()).map(RecordUpdate::getOld).map(SignalStorageRecord::getId).toList()); Set<StorageId> completeKeys = new HashSet<>(currentLocalStorageKeys); completeKeys.addAll(Stream.of(mergeResult.getAllNewRecords()).map(SignalRecord::getId).toList()); completeKeys.removeAll(Stream.of(mergeResult.getAllRemovedRecords()).map(SignalRecord::getId).toList()); completeKeys.addAll(Stream.of(inserts).map(SignalStorageRecord::getId).toList()); completeKeys.removeAll(deletes); SignalStorageManifest manifest = new SignalStorageManifest(currentManifestVersion + 1, new ArrayList<>(completeKeys)); return new WriteOperationResult(manifest, inserts, Stream.of(deletes).map(StorageId::getRaw).toList()); }  }
StorageSyncHelper { public static @NonNull WriteOperationResult createWriteOperation(long currentManifestVersion, @NonNull List<StorageId> currentLocalStorageKeys, @NonNull MergeResult mergeResult) { List<SignalStorageRecord> inserts = new ArrayList<>(); inserts.addAll(mergeResult.getRemoteInserts()); inserts.addAll(Stream.of(mergeResult.getRemoteUpdates()).map(RecordUpdate::getNew).toList()); List<StorageId> deletes = new ArrayList<>(); deletes.addAll(Stream.of(mergeResult.getRemoteDeletes()).map(SignalRecord::getId).toList()); deletes.addAll(Stream.of(mergeResult.getRemoteUpdates()).map(RecordUpdate::getOld).map(SignalStorageRecord::getId).toList()); Set<StorageId> completeKeys = new HashSet<>(currentLocalStorageKeys); completeKeys.addAll(Stream.of(mergeResult.getAllNewRecords()).map(SignalRecord::getId).toList()); completeKeys.removeAll(Stream.of(mergeResult.getAllRemovedRecords()).map(SignalRecord::getId).toList()); completeKeys.addAll(Stream.of(inserts).map(SignalStorageRecord::getId).toList()); completeKeys.removeAll(deletes); SignalStorageManifest manifest = new SignalStorageManifest(currentManifestVersion + 1, new ArrayList<>(completeKeys)); return new WriteOperationResult(manifest, inserts, Stream.of(deletes).map(StorageId::getRaw).toList()); }  static @NonNull Optional<LocalWriteResult> buildStorageUpdatesForLocal(long currentManifestVersion,
                                                                                @NonNull List<StorageId> currentLocalKeys,
                                                                                @NonNull List<RecipientSettings> updates,
                                                                                @NonNull List<RecipientSettings> inserts,
                                                                                @NonNull List<RecipientSettings> deletes,
                                                                                @NonNull Optional<SignalAccountRecord> accountUpdate,
                                                                                @NonNull Optional<SignalAccountRecord> accountInsert); static @NonNull KeyDifferenceResult findKeyDifference(@NonNull Collection<StorageId> remoteKeys,
                                                               @NonNull Collection<StorageId> localKeys); static @NonNull MergeResult resolveConflict(@NonNull Collection<SignalStorageRecord> remoteOnlyRecords,
                                                     @NonNull Collection<SignalStorageRecord> localOnlyRecords); static @NonNull WriteOperationResult createWriteOperation(long currentManifestVersion,
                                                                   @NonNull List<StorageId> currentLocalStorageKeys,
                                                                   @NonNull MergeResult mergeResult); static @NonNull byte[] generateKey(); static boolean profileKeyChanged(RecordUpdate<SignalContactRecord> update); static Optional<SignalAccountRecord> getPendingAccountSyncUpdate(@NonNull Context context, @NonNull Recipient self); static Optional<SignalAccountRecord> getPendingAccountSyncInsert(@NonNull Context context, @NonNull Recipient self); static SignalStorageRecord buildAccountRecord(@NonNull Context context, @NonNull Recipient self); static void applyAccountStorageSyncUpdates(@NonNull Context context, Optional<StorageSyncHelper.RecordUpdate<SignalAccountRecord>> update); static void applyAccountStorageSyncUpdates(@NonNull Context context, @NonNull StorageId storageId, @NonNull SignalAccountRecord update, boolean fetchProfile); static void scheduleSyncForDataChange(); static void scheduleRoutineSync(); }
StorageSyncHelper { public static @NonNull WriteOperationResult createWriteOperation(long currentManifestVersion, @NonNull List<StorageId> currentLocalStorageKeys, @NonNull MergeResult mergeResult) { List<SignalStorageRecord> inserts = new ArrayList<>(); inserts.addAll(mergeResult.getRemoteInserts()); inserts.addAll(Stream.of(mergeResult.getRemoteUpdates()).map(RecordUpdate::getNew).toList()); List<StorageId> deletes = new ArrayList<>(); deletes.addAll(Stream.of(mergeResult.getRemoteDeletes()).map(SignalRecord::getId).toList()); deletes.addAll(Stream.of(mergeResult.getRemoteUpdates()).map(RecordUpdate::getOld).map(SignalStorageRecord::getId).toList()); Set<StorageId> completeKeys = new HashSet<>(currentLocalStorageKeys); completeKeys.addAll(Stream.of(mergeResult.getAllNewRecords()).map(SignalRecord::getId).toList()); completeKeys.removeAll(Stream.of(mergeResult.getAllRemovedRecords()).map(SignalRecord::getId).toList()); completeKeys.addAll(Stream.of(inserts).map(SignalStorageRecord::getId).toList()); completeKeys.removeAll(deletes); SignalStorageManifest manifest = new SignalStorageManifest(currentManifestVersion + 1, new ArrayList<>(completeKeys)); return new WriteOperationResult(manifest, inserts, Stream.of(deletes).map(StorageId::getRaw).toList()); }  static @NonNull Optional<LocalWriteResult> buildStorageUpdatesForLocal(long currentManifestVersion,
                                                                                @NonNull List<StorageId> currentLocalKeys,
                                                                                @NonNull List<RecipientSettings> updates,
                                                                                @NonNull List<RecipientSettings> inserts,
                                                                                @NonNull List<RecipientSettings> deletes,
                                                                                @NonNull Optional<SignalAccountRecord> accountUpdate,
                                                                                @NonNull Optional<SignalAccountRecord> accountInsert); static @NonNull KeyDifferenceResult findKeyDifference(@NonNull Collection<StorageId> remoteKeys,
                                                               @NonNull Collection<StorageId> localKeys); static @NonNull MergeResult resolveConflict(@NonNull Collection<SignalStorageRecord> remoteOnlyRecords,
                                                     @NonNull Collection<SignalStorageRecord> localOnlyRecords); static @NonNull WriteOperationResult createWriteOperation(long currentManifestVersion,
                                                                   @NonNull List<StorageId> currentLocalStorageKeys,
                                                                   @NonNull MergeResult mergeResult); static @NonNull byte[] generateKey(); static boolean profileKeyChanged(RecordUpdate<SignalContactRecord> update); static Optional<SignalAccountRecord> getPendingAccountSyncUpdate(@NonNull Context context, @NonNull Recipient self); static Optional<SignalAccountRecord> getPendingAccountSyncInsert(@NonNull Context context, @NonNull Recipient self); static SignalStorageRecord buildAccountRecord(@NonNull Context context, @NonNull Recipient self); static void applyAccountStorageSyncUpdates(@NonNull Context context, Optional<StorageSyncHelper.RecordUpdate<SignalAccountRecord>> update); static void applyAccountStorageSyncUpdates(@NonNull Context context, @NonNull StorageId storageId, @NonNull SignalAccountRecord update, boolean fetchProfile); static void scheduleSyncForDataChange(); static void scheduleRoutineSync();  }