@Test public void merge_fillInGaps_treatNamePartsAsOneUnit() { SignalContactRecord remote = new SignalContactRecord.Builder(byteArray(1), new SignalServiceAddress(UUID_A, null)) .setBlocked(true) .setGivenName("AFirst") .setFamilyName("") .setProfileSharingEnabled(true) .build(); SignalContactRecord local = new SignalContactRecord.Builder(byteArray(2), new SignalServiceAddress(UUID_B, E164_B)) .setBlocked(false) .setIdentityKey(byteArray(2)) .setProfileKey(byteArray(3)) .setGivenName("BFirst") .setFamilyName("BLast") .setUsername("username B") .setProfileSharingEnabled(false) .build(); SignalContactRecord merged = new ContactConflictMerger(Collections.singletonList(local), SELF).merge(remote, local, mock(KeyGenerator.class)); assertEquals(UUID_A, merged.getAddress().getUuid().get()); assertEquals(E164_B, merged.getAddress().getNumber().get()); assertTrue(merged.isBlocked()); assertArrayEquals(byteArray(2), merged.getIdentityKey().get()); assertEquals(IdentityState.DEFAULT, merged.getIdentityState()); assertArrayEquals(byteArray(3), merged.getProfileKey().get()); assertEquals("AFirst", merged.getGivenName().get()); assertFalse(merged.getFamilyName().isPresent()); assertEquals("username B", merged.getUsername().get()); assertTrue(merged.isProfileSharingEnabled()); }
@Override public @NonNull SignalContactRecord merge(@NonNull SignalContactRecord remote, @NonNull SignalContactRecord local, @NonNull StorageSyncHelper.KeyGenerator keyGenerator) { String givenName; String familyName; if (remote.getGivenName().isPresent() || remote.getFamilyName().isPresent()) { givenName = remote.getGivenName().or(""); familyName = remote.getFamilyName().or(""); } else { givenName = local.getGivenName().or(""); familyName = local.getFamilyName().or(""); } byte[] unknownFields = remote.serializeUnknownFields(); UUID uuid = remote.getAddress().getUuid().or(local.getAddress().getUuid()).orNull(); String e164 = remote.getAddress().getNumber().or(local.getAddress().getNumber()).orNull(); SignalServiceAddress address = new SignalServiceAddress(uuid, e164); byte[] profileKey = remote.getProfileKey().or(local.getProfileKey()).orNull(); String username = remote.getUsername().or(local.getUsername()).or(""); IdentityState identityState = remote.getIdentityState(); byte[] identityKey = remote.getIdentityKey().or(local.getIdentityKey()).orNull(); boolean blocked = remote.isBlocked(); boolean profileSharing = remote.isProfileSharingEnabled(); boolean archived = remote.isArchived(); boolean forcedUnread = remote.isForcedUnread(); boolean matchesRemote = doParamsMatch(remote, unknownFields, address, givenName, familyName, profileKey, username, identityState, identityKey, blocked, profileSharing, archived, forcedUnread); boolean matchesLocal = doParamsMatch(local, unknownFields, address, givenName, familyName, profileKey, username, identityState, identityKey, blocked, profileSharing, archived, forcedUnread); if (matchesRemote) { return remote; } else if (matchesLocal) { return local; } else { return new SignalContactRecord.Builder(keyGenerator.generate(), address) .setUnknownFields(unknownFields) .setGivenName(givenName) .setFamilyName(familyName) .setProfileKey(profileKey) .setUsername(username) .setIdentityState(identityState) .setIdentityKey(identityKey) .setBlocked(blocked) .setProfileSharingEnabled(profileSharing) .setForcedUnread(forcedUnread) .build(); } }
ContactConflictMerger implements StorageSyncHelper.ConflictMerger<SignalContactRecord> { @Override public @NonNull SignalContactRecord merge(@NonNull SignalContactRecord remote, @NonNull SignalContactRecord local, @NonNull StorageSyncHelper.KeyGenerator keyGenerator) { String givenName; String familyName; if (remote.getGivenName().isPresent() || remote.getFamilyName().isPresent()) { givenName = remote.getGivenName().or(""); familyName = remote.getFamilyName().or(""); } else { givenName = local.getGivenName().or(""); familyName = local.getFamilyName().or(""); } byte[] unknownFields = remote.serializeUnknownFields(); UUID uuid = remote.getAddress().getUuid().or(local.getAddress().getUuid()).orNull(); String e164 = remote.getAddress().getNumber().or(local.getAddress().getNumber()).orNull(); SignalServiceAddress address = new SignalServiceAddress(uuid, e164); byte[] profileKey = remote.getProfileKey().or(local.getProfileKey()).orNull(); String username = remote.getUsername().or(local.getUsername()).or(""); IdentityState identityState = remote.getIdentityState(); byte[] identityKey = remote.getIdentityKey().or(local.getIdentityKey()).orNull(); boolean blocked = remote.isBlocked(); boolean profileSharing = remote.isProfileSharingEnabled(); boolean archived = remote.isArchived(); boolean forcedUnread = remote.isForcedUnread(); boolean matchesRemote = doParamsMatch(remote, unknownFields, address, givenName, familyName, profileKey, username, identityState, identityKey, blocked, profileSharing, archived, forcedUnread); boolean matchesLocal = doParamsMatch(local, unknownFields, address, givenName, familyName, profileKey, username, identityState, identityKey, blocked, profileSharing, archived, forcedUnread); if (matchesRemote) { return remote; } else if (matchesLocal) { return local; } else { return new SignalContactRecord.Builder(keyGenerator.generate(), address) .setUnknownFields(unknownFields) .setGivenName(givenName) .setFamilyName(familyName) .setProfileKey(profileKey) .setUsername(username) .setIdentityState(identityState) .setIdentityKey(identityKey) .setBlocked(blocked) .setProfileSharingEnabled(profileSharing) .setForcedUnread(forcedUnread) .build(); } } }
ContactConflictMerger implements StorageSyncHelper.ConflictMerger<SignalContactRecord> { @Override public @NonNull SignalContactRecord merge(@NonNull SignalContactRecord remote, @NonNull SignalContactRecord local, @NonNull StorageSyncHelper.KeyGenerator keyGenerator) { String givenName; String familyName; if (remote.getGivenName().isPresent() || remote.getFamilyName().isPresent()) { givenName = remote.getGivenName().or(""); familyName = remote.getFamilyName().or(""); } else { givenName = local.getGivenName().or(""); familyName = local.getFamilyName().or(""); } byte[] unknownFields = remote.serializeUnknownFields(); UUID uuid = remote.getAddress().getUuid().or(local.getAddress().getUuid()).orNull(); String e164 = remote.getAddress().getNumber().or(local.getAddress().getNumber()).orNull(); SignalServiceAddress address = new SignalServiceAddress(uuid, e164); byte[] profileKey = remote.getProfileKey().or(local.getProfileKey()).orNull(); String username = remote.getUsername().or(local.getUsername()).or(""); IdentityState identityState = remote.getIdentityState(); byte[] identityKey = remote.getIdentityKey().or(local.getIdentityKey()).orNull(); boolean blocked = remote.isBlocked(); boolean profileSharing = remote.isProfileSharingEnabled(); boolean archived = remote.isArchived(); boolean forcedUnread = remote.isForcedUnread(); boolean matchesRemote = doParamsMatch(remote, unknownFields, address, givenName, familyName, profileKey, username, identityState, identityKey, blocked, profileSharing, archived, forcedUnread); boolean matchesLocal = doParamsMatch(local, unknownFields, address, givenName, familyName, profileKey, username, identityState, identityKey, blocked, profileSharing, archived, forcedUnread); if (matchesRemote) { return remote; } else if (matchesLocal) { return local; } else { return new SignalContactRecord.Builder(keyGenerator.generate(), address) .setUnknownFields(unknownFields) .setGivenName(givenName) .setFamilyName(familyName) .setProfileKey(profileKey) .setUsername(username) .setIdentityState(identityState) .setIdentityKey(identityKey) .setBlocked(blocked) .setProfileSharingEnabled(profileSharing) .setForcedUnread(forcedUnread) .build(); } } ContactConflictMerger(@NonNull Collection<SignalContactRecord> localOnly, @NonNull Recipient self); }
ContactConflictMerger implements StorageSyncHelper.ConflictMerger<SignalContactRecord> { @Override public @NonNull SignalContactRecord merge(@NonNull SignalContactRecord remote, @NonNull SignalContactRecord local, @NonNull StorageSyncHelper.KeyGenerator keyGenerator) { String givenName; String familyName; if (remote.getGivenName().isPresent() || remote.getFamilyName().isPresent()) { givenName = remote.getGivenName().or(""); familyName = remote.getFamilyName().or(""); } else { givenName = local.getGivenName().or(""); familyName = local.getFamilyName().or(""); } byte[] unknownFields = remote.serializeUnknownFields(); UUID uuid = remote.getAddress().getUuid().or(local.getAddress().getUuid()).orNull(); String e164 = remote.getAddress().getNumber().or(local.getAddress().getNumber()).orNull(); SignalServiceAddress address = new SignalServiceAddress(uuid, e164); byte[] profileKey = remote.getProfileKey().or(local.getProfileKey()).orNull(); String username = remote.getUsername().or(local.getUsername()).or(""); IdentityState identityState = remote.getIdentityState(); byte[] identityKey = remote.getIdentityKey().or(local.getIdentityKey()).orNull(); boolean blocked = remote.isBlocked(); boolean profileSharing = remote.isProfileSharingEnabled(); boolean archived = remote.isArchived(); boolean forcedUnread = remote.isForcedUnread(); boolean matchesRemote = doParamsMatch(remote, unknownFields, address, givenName, familyName, profileKey, username, identityState, identityKey, blocked, profileSharing, archived, forcedUnread); boolean matchesLocal = doParamsMatch(local, unknownFields, address, givenName, familyName, profileKey, username, identityState, identityKey, blocked, profileSharing, archived, forcedUnread); if (matchesRemote) { return remote; } else if (matchesLocal) { return local; } else { return new SignalContactRecord.Builder(keyGenerator.generate(), address) .setUnknownFields(unknownFields) .setGivenName(givenName) .setFamilyName(familyName) .setProfileKey(profileKey) .setUsername(username) .setIdentityState(identityState) .setIdentityKey(identityKey) .setBlocked(blocked) .setProfileSharingEnabled(profileSharing) .setForcedUnread(forcedUnread) .build(); } } ContactConflictMerger(@NonNull Collection<SignalContactRecord> localOnly, @NonNull Recipient self); @Override @NonNull Optional<SignalContactRecord> getMatching(@NonNull SignalContactRecord record); @Override @NonNull Collection<SignalContactRecord> getInvalidEntries(@NonNull Collection<SignalContactRecord> remoteRecords); @Override @NonNull SignalContactRecord merge(@NonNull SignalContactRecord remote, @NonNull SignalContactRecord local, @NonNull StorageSyncHelper.KeyGenerator keyGenerator); }
ContactConflictMerger implements StorageSyncHelper.ConflictMerger<SignalContactRecord> { @Override public @NonNull SignalContactRecord merge(@NonNull SignalContactRecord remote, @NonNull SignalContactRecord local, @NonNull StorageSyncHelper.KeyGenerator keyGenerator) { String givenName; String familyName; if (remote.getGivenName().isPresent() || remote.getFamilyName().isPresent()) { givenName = remote.getGivenName().or(""); familyName = remote.getFamilyName().or(""); } else { givenName = local.getGivenName().or(""); familyName = local.getFamilyName().or(""); } byte[] unknownFields = remote.serializeUnknownFields(); UUID uuid = remote.getAddress().getUuid().or(local.getAddress().getUuid()).orNull(); String e164 = remote.getAddress().getNumber().or(local.getAddress().getNumber()).orNull(); SignalServiceAddress address = new SignalServiceAddress(uuid, e164); byte[] profileKey = remote.getProfileKey().or(local.getProfileKey()).orNull(); String username = remote.getUsername().or(local.getUsername()).or(""); IdentityState identityState = remote.getIdentityState(); byte[] identityKey = remote.getIdentityKey().or(local.getIdentityKey()).orNull(); boolean blocked = remote.isBlocked(); boolean profileSharing = remote.isProfileSharingEnabled(); boolean archived = remote.isArchived(); boolean forcedUnread = remote.isForcedUnread(); boolean matchesRemote = doParamsMatch(remote, unknownFields, address, givenName, familyName, profileKey, username, identityState, identityKey, blocked, profileSharing, archived, forcedUnread); boolean matchesLocal = doParamsMatch(local, unknownFields, address, givenName, familyName, profileKey, username, identityState, identityKey, blocked, profileSharing, archived, forcedUnread); if (matchesRemote) { return remote; } else if (matchesLocal) { return local; } else { return new SignalContactRecord.Builder(keyGenerator.generate(), address) .setUnknownFields(unknownFields) .setGivenName(givenName) .setFamilyName(familyName) .setProfileKey(profileKey) .setUsername(username) .setIdentityState(identityState) .setIdentityKey(identityKey) .setBlocked(blocked) .setProfileSharingEnabled(profileSharing) .setForcedUnread(forcedUnread) .build(); } } ContactConflictMerger(@NonNull Collection<SignalContactRecord> localOnly, @NonNull Recipient self); @Override @NonNull Optional<SignalContactRecord> getMatching(@NonNull SignalContactRecord record); @Override @NonNull Collection<SignalContactRecord> getInvalidEntries(@NonNull Collection<SignalContactRecord> remoteRecords); @Override @NonNull SignalContactRecord merge(@NonNull SignalContactRecord remote, @NonNull SignalContactRecord local, @NonNull StorageSyncHelper.KeyGenerator keyGenerator);  }