Add support for system names on the ContactRecord.

fork-5.53.8
Greyson Parrelli 2022-09-28 14:09:44 -04:00
rodzic 6e5f28339d
commit 1999db97f2
11 zmienionych plików z 197 dodań i 66 usunięć

Wyświetl plik

@ -925,6 +925,21 @@ open class RecipientDatabase(context: Context, databaseHelper: SignalDatabase) :
ApplicationDependencies.getDatabaseObserver().notifyRecipientChanged(recipientId) ApplicationDependencies.getDatabaseObserver().notifyRecipientChanged(recipientId)
} }
fun markAllSystemContactsNeedsSync() {
writableDatabase.withinTransaction { db ->
db
.select(ID)
.from(TABLE_NAME)
.where("$SYSTEM_CONTACT_URI NOT NULL")
.run()
.use { cursor ->
while (cursor.moveToNext()) {
rotateStorageId(RecipientId.from(cursor.requireLong(ID)))
}
}
}
}
fun applyStorageIdUpdates(storageIds: Map<RecipientId, StorageId>) { fun applyStorageIdUpdates(storageIds: Map<RecipientId, StorageId>) {
val db = writableDatabase val db = writableDatabase
db.beginTransaction() db.beginTransaction()
@ -3667,8 +3682,9 @@ open class RecipientDatabase(context: Context, databaseHelper: SignalDatabase) :
private fun getValuesForStorageContact(contact: SignalContactRecord, isInsert: Boolean): ContentValues { private fun getValuesForStorageContact(contact: SignalContactRecord, isInsert: Boolean): ContentValues {
return ContentValues().apply { return ContentValues().apply {
val profileName = ProfileName.fromParts(contact.givenName.orElse(null), contact.familyName.orElse(null)) val profileName = ProfileName.fromParts(contact.profileGivenName.orElse(null), contact.profileFamilyName.orElse(null))
val username: String? = contact.username.orElse(null) val systemName = ProfileName.fromParts(contact.systemGivenName.orElse(null), contact.systemFamilyName.orElse(null))
val username = contact.username.orElse(null)
if (contact.serviceId.isValid) { if (contact.serviceId.isValid) {
put(SERVICE_ID, contact.serviceId.toString()) put(SERVICE_ID, contact.serviceId.toString())
@ -3682,6 +3698,9 @@ open class RecipientDatabase(context: Context, databaseHelper: SignalDatabase) :
put(PROFILE_GIVEN_NAME, profileName.givenName) put(PROFILE_GIVEN_NAME, profileName.givenName)
put(PROFILE_FAMILY_NAME, profileName.familyName) put(PROFILE_FAMILY_NAME, profileName.familyName)
put(PROFILE_JOINED_NAME, profileName.toString()) put(PROFILE_JOINED_NAME, profileName.toString())
put(SYSTEM_GIVEN_NAME, systemName.givenName)
put(SYSTEM_FAMILY_NAME, systemName.familyName)
put(SYSTEM_JOINED_NAME, systemName.toString())
put(PROFILE_KEY, contact.profileKey.map { source -> Base64.encodeBytes(source) }.orElse(null)) put(PROFILE_KEY, contact.profileKey.map { source -> Base64.encodeBytes(source) }.orElse(null))
put(USERNAME, if (TextUtils.isEmpty(username)) null else username) put(USERNAME, if (TextUtils.isEmpty(username)) null else username)
put(PROFILE_SHARING, if (contact.isProfileSharingEnabled) "1" else "0") put(PROFILE_SHARING, if (contact.isProfileSharingEnabled) "1" else "0")

Wyświetl plik

@ -61,6 +61,7 @@ import org.thoughtcrime.securesms.migrations.StickerLaunchMigrationJob;
import org.thoughtcrime.securesms.migrations.StickerMyDailyLifeMigrationJob; import org.thoughtcrime.securesms.migrations.StickerMyDailyLifeMigrationJob;
import org.thoughtcrime.securesms.migrations.StorageCapabilityMigrationJob; import org.thoughtcrime.securesms.migrations.StorageCapabilityMigrationJob;
import org.thoughtcrime.securesms.migrations.StorageServiceMigrationJob; import org.thoughtcrime.securesms.migrations.StorageServiceMigrationJob;
import org.thoughtcrime.securesms.migrations.StorageServiceSystemNameMigrationJob;
import org.thoughtcrime.securesms.migrations.SyncDistributionListsMigrationJob; import org.thoughtcrime.securesms.migrations.SyncDistributionListsMigrationJob;
import org.thoughtcrime.securesms.migrations.TrimByLengthSettingsMigrationJob; import org.thoughtcrime.securesms.migrations.TrimByLengthSettingsMigrationJob;
import org.thoughtcrime.securesms.migrations.UserNotificationMigrationJob; import org.thoughtcrime.securesms.migrations.UserNotificationMigrationJob;
@ -221,6 +222,7 @@ public final class JobManagerFactories {
put(StickerMyDailyLifeMigrationJob.KEY, new StickerMyDailyLifeMigrationJob.Factory()); put(StickerMyDailyLifeMigrationJob.KEY, new StickerMyDailyLifeMigrationJob.Factory());
put(StorageCapabilityMigrationJob.KEY, new StorageCapabilityMigrationJob.Factory()); put(StorageCapabilityMigrationJob.KEY, new StorageCapabilityMigrationJob.Factory());
put(StorageServiceMigrationJob.KEY, new StorageServiceMigrationJob.Factory()); put(StorageServiceMigrationJob.KEY, new StorageServiceMigrationJob.Factory());
put(StorageServiceSystemNameMigrationJob.KEY, new StorageServiceSystemNameMigrationJob.Factory());
put(TrimByLengthSettingsMigrationJob.KEY, new TrimByLengthSettingsMigrationJob.Factory()); put(TrimByLengthSettingsMigrationJob.KEY, new TrimByLengthSettingsMigrationJob.Factory());
put(UserNotificationMigrationJob.KEY, new UserNotificationMigrationJob.Factory()); put(UserNotificationMigrationJob.KEY, new UserNotificationMigrationJob.Factory());
put(UuidMigrationJob.KEY, new UuidMigrationJob.Factory()); put(UuidMigrationJob.KEY, new UuidMigrationJob.Factory());

Wyświetl plik

@ -108,9 +108,10 @@ public class ApplicationMigrations {
static final int REFRESH_PNI_REGISTRATION_ID = 64; static final int REFRESH_PNI_REGISTRATION_ID = 64;
static final int KBS_MIGRATION_2 = 65; static final int KBS_MIGRATION_2 = 65;
static final int PNI_2 = 66; static final int PNI_2 = 66;
static final int SYSTEM_NAME_SYNC = 67;
} }
public static final int CURRENT_VERSION = 66; public static final int CURRENT_VERSION = 67;
/** /**
* This *must* be called after the {@link JobManager} has been instantiated, but *before* the call * This *must* be called after the {@link JobManager} has been instantiated, but *before* the call
@ -476,6 +477,10 @@ public class ApplicationMigrations {
jobs.put(Version.PNI_2, new PniMigrationJob()); jobs.put(Version.PNI_2, new PniMigrationJob());
} }
if (lastSeenVersion < Version.SYSTEM_NAME_SYNC) {
jobs.put(Version.SYSTEM_NAME_SYNC, new StorageServiceSystemNameMigrationJob());
}
return jobs; return jobs;
} }

Wyświetl plik

@ -0,0 +1,56 @@
package org.thoughtcrime.securesms.migrations;
import androidx.annotation.NonNull;
import org.thoughtcrime.securesms.database.SignalDatabase;
import org.thoughtcrime.securesms.dependencies.ApplicationDependencies;
import org.thoughtcrime.securesms.jobmanager.Data;
import org.thoughtcrime.securesms.jobmanager.Job;
import org.thoughtcrime.securesms.jobs.DownloadLatestEmojiDataJob;
import org.thoughtcrime.securesms.jobs.EmojiSearchIndexDownloadJob;
import org.thoughtcrime.securesms.storage.StorageSyncHelper;
/**
* Added for when we started syncing contact names in storage service.
* Rotates the storageId of every system contact and then schedules a storage sync.
*/
public final class StorageServiceSystemNameMigrationJob extends MigrationJob {
public static final String KEY = "StorageServiceSystemNameMigrationJob";
StorageServiceSystemNameMigrationJob() {
this(new Parameters.Builder().build());
}
private StorageServiceSystemNameMigrationJob(@NonNull Parameters parameters) {
super(parameters);
}
@Override
public boolean isUiBlocking() {
return false;
}
@Override
public @NonNull String getFactoryKey() {
return KEY;
}
@Override
public void performMigration() {
SignalDatabase.recipients().markAllSystemContactsNeedsSync();
StorageSyncHelper.scheduleSyncForDataChange();
}
@Override
boolean shouldRetry(@NonNull Exception e) {
return false;
}
public static class Factory implements Job.Factory<StorageServiceSystemNameMigrationJob> {
@Override
public @NonNull StorageServiceSystemNameMigrationJob create(@NonNull Parameters parameters, @NonNull Data data) {
return new StorageServiceSystemNameMigrationJob(parameters);
}
}
}

Wyświetl plik

@ -1,7 +1,5 @@
package org.thoughtcrime.securesms.storage; package org.thoughtcrime.securesms.storage;
import android.content.Context;
import androidx.annotation.NonNull; import androidx.annotation.NonNull;
import androidx.annotation.Nullable; import androidx.annotation.Nullable;
@ -17,7 +15,6 @@ import org.thoughtcrime.securesms.util.FeatureFlags;
import org.whispersystems.signalservice.api.push.ACI; import org.whispersystems.signalservice.api.push.ACI;
import org.whispersystems.signalservice.api.push.PNI; import org.whispersystems.signalservice.api.push.PNI;
import org.whispersystems.signalservice.api.push.ServiceId; import org.whispersystems.signalservice.api.push.ServiceId;
import org.whispersystems.signalservice.api.push.SignalServiceAddress;
import org.whispersystems.signalservice.api.storage.SignalContactRecord; import org.whispersystems.signalservice.api.storage.SignalContactRecord;
import org.whispersystems.signalservice.api.util.OptionalUtil; import org.whispersystems.signalservice.api.util.OptionalUtil;
import org.whispersystems.signalservice.internal.storage.protos.ContactRecord.IdentityState; import org.whispersystems.signalservice.internal.storage.protos.ContactRecord.IdentityState;
@ -122,15 +119,15 @@ public class ContactRecordProcessor extends DefaultStorageRecordProcessor<Signal
remote = remote.withoutPni(); remote = remote.withoutPni();
} }
String givenName; String profileGivenName;
String familyName; String profileFamilyName;
if (remote.getGivenName().isPresent() || remote.getFamilyName().isPresent()) { if (remote.getProfileGivenName().isPresent() || remote.getProfileFamilyName().isPresent()) {
givenName = remote.getGivenName().orElse(""); profileGivenName = remote.getProfileGivenName().orElse("");
familyName = remote.getFamilyName().orElse(""); profileFamilyName = remote.getProfileFamilyName().orElse("");
} else { } else {
givenName = local.getGivenName().orElse(""); profileGivenName = local.getProfileGivenName().orElse("");
familyName = local.getFamilyName().orElse(""); profileFamilyName = local.getProfileFamilyName().orElse("");
} }
IdentityState identityState; IdentityState identityState;
@ -198,8 +195,10 @@ public class ContactRecordProcessor extends DefaultStorageRecordProcessor<Signal
boolean hideStory = remote.shouldHideStory(); boolean hideStory = remote.shouldHideStory();
long unregisteredTimestamp = remote.getUnregisteredTimestamp(); long unregisteredTimestamp = remote.getUnregisteredTimestamp();
boolean hidden = remote.isHidden(); boolean hidden = remote.isHidden();
boolean matchesRemote = doParamsMatch(remote, unknownFields, serviceId, pni, e164, givenName, familyName, profileKey, username, identityState, identityKey, blocked, profileSharing, archived, forcedUnread, muteUntil, hideStory, unregisteredTimestamp, hidden); String systemGivenName = SignalStore.account().isPrimaryDevice() ? local.getSystemGivenName().orElse("") : remote.getSystemGivenName().orElse("");
boolean matchesLocal = doParamsMatch(local, unknownFields, serviceId, pni, e164, givenName, familyName, profileKey, username, identityState, identityKey, blocked, profileSharing, archived, forcedUnread, muteUntil, hideStory, unregisteredTimestamp, hidden); String systemFamilyName = SignalStore.account().isPrimaryDevice() ? local.getSystemFamilyName().orElse("") : remote.getSystemFamilyName().orElse("");
boolean matchesRemote = doParamsMatch(remote, unknownFields, serviceId, pni, e164, profileGivenName, profileFamilyName, systemGivenName, systemFamilyName, profileKey, username, identityState, identityKey, blocked, profileSharing, archived, forcedUnread, muteUntil, hideStory, unregisteredTimestamp, hidden);
boolean matchesLocal = doParamsMatch(local, unknownFields, serviceId, pni, e164, profileGivenName, profileFamilyName, systemGivenName, systemFamilyName, profileKey, username, identityState, identityKey, blocked, profileSharing, archived, forcedUnread, muteUntil, hideStory, unregisteredTimestamp, hidden);
if (matchesRemote) { if (matchesRemote) {
return remote; return remote;
@ -209,8 +208,10 @@ public class ContactRecordProcessor extends DefaultStorageRecordProcessor<Signal
return new SignalContactRecord.Builder(keyGenerator.generate(), serviceId, unknownFields) return new SignalContactRecord.Builder(keyGenerator.generate(), serviceId, unknownFields)
.setE164(e164) .setE164(e164)
.setPni(pni) .setPni(pni)
.setGivenName(givenName) .setProfileGivenName(profileGivenName)
.setFamilyName(familyName) .setProfileFamilyName(profileFamilyName)
.setSystemGivenName(systemGivenName)
.setSystemFamilyName(systemFamilyName)
.setProfileKey(profileKey) .setProfileKey(profileKey)
.setUsername(username) .setUsername(username)
.setIdentityState(identityState) .setIdentityState(identityState)
@ -254,8 +255,10 @@ public class ContactRecordProcessor extends DefaultStorageRecordProcessor<Signal
@NonNull ServiceId serviceId, @NonNull ServiceId serviceId,
@Nullable PNI pni, @Nullable PNI pni,
@Nullable String e164, @Nullable String e164,
@NonNull String givenName, @NonNull String profileGivenName,
@NonNull String familyName, @NonNull String profileFamilyName,
@NonNull String systemGivenName,
@NonNull String systemFamilyName,
@Nullable byte[] profileKey, @Nullable byte[] profileKey,
@NonNull String username, @NonNull String username,
@Nullable IdentityState identityState, @Nullable IdentityState identityState,
@ -269,23 +272,25 @@ public class ContactRecordProcessor extends DefaultStorageRecordProcessor<Signal
long unregisteredTimestamp, long unregisteredTimestamp,
boolean hidden) boolean hidden)
{ {
return Arrays.equals(contact.serializeUnknownFields(), unknownFields) && return Arrays.equals(contact.serializeUnknownFields(), unknownFields) &&
Objects.equals(contact.getServiceId(), serviceId) && Objects.equals(contact.getServiceId(), serviceId) &&
Objects.equals(contact.getPni().orElse(null), pni) && Objects.equals(contact.getPni().orElse(null), pni) &&
Objects.equals(contact.getNumber().orElse(null), e164) && Objects.equals(contact.getNumber().orElse(null), e164) &&
Objects.equals(contact.getGivenName().orElse(""), givenName) && Objects.equals(contact.getProfileGivenName().orElse(""), profileGivenName) &&
Objects.equals(contact.getFamilyName().orElse(""), familyName) && Objects.equals(contact.getProfileFamilyName().orElse(""), profileFamilyName) &&
Arrays.equals(contact.getProfileKey().orElse(null), profileKey) && Objects.equals(contact.getSystemGivenName().orElse(""), systemGivenName) &&
Objects.equals(contact.getUsername().orElse(""), username) && Objects.equals(contact.getSystemFamilyName().orElse(""), systemFamilyName) &&
Objects.equals(contact.getIdentityState(), identityState) && Arrays.equals(contact.getProfileKey().orElse(null), profileKey) &&
Arrays.equals(contact.getIdentityKey().orElse(null), identityKey) && Objects.equals(contact.getUsername().orElse(""), username) &&
contact.isBlocked() == blocked && Objects.equals(contact.getIdentityState(), identityState) &&
contact.isProfileSharingEnabled() == profileSharing && Arrays.equals(contact.getIdentityKey().orElse(null), identityKey) &&
contact.isArchived() == archived && contact.isBlocked() == blocked &&
contact.isForcedUnread() == forcedUnread && contact.isProfileSharingEnabled() == profileSharing &&
contact.getMuteUntil() == muteUntil && contact.isArchived() == archived &&
contact.shouldHideStory() == hideStory && contact.isForcedUnread() == forcedUnread &&
contact.getUnregisteredTimestamp() == unregisteredTimestamp && contact.getMuteUntil() == muteUntil &&
contact.shouldHideStory() == hideStory &&
contact.getUnregisteredTimestamp() == unregisteredTimestamp &&
contact.isHidden() == hidden; contact.isHidden() == hidden;
} }
} }

Wyświetl plik

@ -11,15 +11,12 @@ import org.thoughtcrime.securesms.database.IdentityDatabase;
import org.thoughtcrime.securesms.database.RecipientDatabase; import org.thoughtcrime.securesms.database.RecipientDatabase;
import org.thoughtcrime.securesms.database.SignalDatabase; import org.thoughtcrime.securesms.database.SignalDatabase;
import org.thoughtcrime.securesms.database.model.DistributionListId; import org.thoughtcrime.securesms.database.model.DistributionListId;
import org.thoughtcrime.securesms.database.model.DistributionListPrivacyMode;
import org.thoughtcrime.securesms.database.model.DistributionListRecord; import org.thoughtcrime.securesms.database.model.DistributionListRecord;
import org.thoughtcrime.securesms.database.model.RecipientRecord; import org.thoughtcrime.securesms.database.model.RecipientRecord;
import org.thoughtcrime.securesms.dependencies.ApplicationDependencies;
import org.thoughtcrime.securesms.groups.GroupId; import org.thoughtcrime.securesms.groups.GroupId;
import org.thoughtcrime.securesms.keyvalue.PhoneNumberPrivacyValues; import org.thoughtcrime.securesms.keyvalue.PhoneNumberPrivacyValues;
import org.thoughtcrime.securesms.recipients.Recipient; import org.thoughtcrime.securesms.recipients.Recipient;
import org.thoughtcrime.securesms.subscription.Subscriber; import org.thoughtcrime.securesms.subscription.Subscriber;
import org.thoughtcrime.securesms.util.FeatureFlags;
import org.whispersystems.signalservice.api.push.ServiceId; import org.whispersystems.signalservice.api.push.ServiceId;
import org.whispersystems.signalservice.api.push.SignalServiceAddress; import org.whispersystems.signalservice.api.push.SignalServiceAddress;
import org.whispersystems.signalservice.api.storage.SignalAccountRecord; import org.whispersystems.signalservice.api.storage.SignalAccountRecord;
@ -34,7 +31,6 @@ import org.whispersystems.signalservice.internal.storage.protos.AccountRecord;
import org.whispersystems.signalservice.internal.storage.protos.ContactRecord.IdentityState; import org.whispersystems.signalservice.internal.storage.protos.ContactRecord.IdentityState;
import org.whispersystems.signalservice.internal.storage.protos.GroupV2Record; import org.whispersystems.signalservice.internal.storage.protos.GroupV2Record;
import java.util.Collections;
import java.util.List; import java.util.List;
import java.util.stream.Collectors; import java.util.stream.Collectors;
@ -116,8 +112,10 @@ public final class StorageSyncModels {
.setE164(recipient.getE164()) .setE164(recipient.getE164())
.setPni(recipient.getPni()) .setPni(recipient.getPni())
.setProfileKey(recipient.getProfileKey()) .setProfileKey(recipient.getProfileKey())
.setGivenName(recipient.getProfileName().getGivenName()) .setProfileGivenName(recipient.getProfileName().getGivenName())
.setFamilyName(recipient.getProfileName().getFamilyName()) .setProfileFamilyName(recipient.getProfileName().getFamilyName())
.setSystemGivenName(recipient.getSystemProfileName().getGivenName())
.setSystemFamilyName(recipient.getSystemProfileName().getFamilyName())
.setBlocked(recipient.isBlocked()) .setBlocked(recipient.isBlocked())
.setProfileSharingEnabled(recipient.isProfileSharing() || recipient.getSystemContactUri() != null) .setProfileSharingEnabled(recipient.isProfileSharing() || recipient.getSystemContactUri() != null)
.setIdentityKey(recipient.getSyncExtras().getIdentityKey()) .setIdentityKey(recipient.getSyncExtras().getIdentityKey())

Wyświetl plik

@ -3,17 +3,23 @@ package org.thoughtcrime.securesms.storage
import org.junit.Assert.assertEquals import org.junit.Assert.assertEquals
import org.junit.Assert.assertFalse import org.junit.Assert.assertFalse
import org.junit.Assert.assertTrue import org.junit.Assert.assertTrue
import org.junit.Before
import org.junit.BeforeClass import org.junit.BeforeClass
import org.junit.Rule import org.junit.Rule
import org.junit.Test import org.junit.Test
import org.mockito.Mock import org.mockito.Mock
import org.mockito.MockedStatic import org.mockito.MockedStatic
import org.mockito.Mockito
import org.mockito.Mockito.mock
import org.mockito.Mockito.`when`
import org.mockito.internal.configuration.plugins.Plugins import org.mockito.internal.configuration.plugins.Plugins
import org.mockito.internal.junit.JUnitRule import org.mockito.internal.junit.JUnitRule
import org.mockito.junit.MockitoRule import org.mockito.junit.MockitoRule
import org.mockito.quality.Strictness import org.mockito.quality.Strictness
import org.signal.core.util.logging.Log import org.signal.core.util.logging.Log
import org.thoughtcrime.securesms.database.RecipientDatabase import org.thoughtcrime.securesms.database.RecipientDatabase
import org.thoughtcrime.securesms.keyvalue.AccountValues
import org.thoughtcrime.securesms.keyvalue.SignalStore
import org.thoughtcrime.securesms.testutil.EmptyLogger import org.thoughtcrime.securesms.testutil.EmptyLogger
import org.thoughtcrime.securesms.util.FeatureFlags import org.thoughtcrime.securesms.util.FeatureFlags
import org.whispersystems.signalservice.api.push.ACI import org.whispersystems.signalservice.api.push.ACI
@ -35,6 +41,16 @@ class ContactRecordProcessorTest {
@Mock @Mock
lateinit var featureFlags: MockedStatic<FeatureFlags> lateinit var featureFlags: MockedStatic<FeatureFlags>
@Mock
lateinit var signalStore: MockedStatic<SignalStore>
@Before
fun setup() {
val mockAccountValues = mock(AccountValues::class.java)
Mockito.lenient().`when`(mockAccountValues.isPrimaryDevice).thenReturn(true)
signalStore.`when`<AccountValues> { SignalStore.account() }.thenReturn(mockAccountValues)
}
@Test @Test
fun `isInvalid, normal, false`() { fun `isInvalid, normal, false`() {
// GIVEN // GIVEN

Wyświetl plik

@ -14,7 +14,6 @@ import org.thoughtcrime.securesms.recipients.Recipient;
import org.thoughtcrime.securesms.storage.StorageSyncHelper.IdDifferenceResult; import org.thoughtcrime.securesms.storage.StorageSyncHelper.IdDifferenceResult;
import org.thoughtcrime.securesms.util.FeatureFlags; import org.thoughtcrime.securesms.util.FeatureFlags;
import org.whispersystems.signalservice.api.push.ServiceId; import org.whispersystems.signalservice.api.push.ServiceId;
import org.whispersystems.signalservice.api.push.SignalServiceAddress;
import org.whispersystems.signalservice.api.storage.SignalAccountRecord; import org.whispersystems.signalservice.api.storage.SignalAccountRecord;
import org.whispersystems.signalservice.api.storage.SignalContactRecord; import org.whispersystems.signalservice.api.storage.SignalContactRecord;
import org.whispersystems.signalservice.api.storage.SignalGroupV1Record; import org.whispersystems.signalservice.api.storage.SignalGroupV1Record;
@ -178,7 +177,7 @@ public final class StorageSyncHelperTest {
{ {
return new SignalContactRecord.Builder(byteArray(key), aci, null) return new SignalContactRecord.Builder(byteArray(key), aci, null)
.setE164(e164) .setE164(e164)
.setGivenName(profileName); .setProfileGivenName(profileName);
} }
private static <E extends SignalRecord> StorageRecordUpdate<E> update(E oldRecord, E newRecord) { private static <E extends SignalRecord> StorageRecordUpdate<E> update(E oldRecord, E newRecord) {

Wyświetl plik

@ -28,8 +28,10 @@ public final class SignalContactRecord implements SignalRecord {
private final ServiceId serviceId; private final ServiceId serviceId;
private final Optional<PNI> pni; private final Optional<PNI> pni;
private final Optional<String> e164; private final Optional<String> e164;
private final Optional<String> givenName; private final Optional<String> profileGivenName;
private final Optional<String> familyName; private final Optional<String> profileFamilyName;
private final Optional<String> systemGivenName;
private final Optional<String> systemFamilyName;
private final Optional<byte[]> profileKey; private final Optional<byte[]> profileKey;
private final Optional<String> username; private final Optional<String> username;
private final Optional<byte[]> identityKey; private final Optional<byte[]> identityKey;
@ -39,14 +41,16 @@ public final class SignalContactRecord implements SignalRecord {
this.proto = proto; this.proto = proto;
this.hasUnknownFields = ProtoUtil.hasUnknownFields(proto); this.hasUnknownFields = ProtoUtil.hasUnknownFields(proto);
this.serviceId = ServiceId.parseOrUnknown(proto.getServiceId()); this.serviceId = ServiceId.parseOrUnknown(proto.getServiceId());
this.pni = OptionalUtil.absentIfEmpty(proto.getServicePni()).map(PNI::parseOrNull); this.pni = OptionalUtil.absentIfEmpty(proto.getServicePni()).map(PNI::parseOrNull);
this.e164 = OptionalUtil.absentIfEmpty(proto.getServiceE164()); this.e164 = OptionalUtil.absentIfEmpty(proto.getServiceE164());
this.givenName = OptionalUtil.absentIfEmpty(proto.getGivenName()); this.profileGivenName = OptionalUtil.absentIfEmpty(proto.getGivenName());
this.familyName = OptionalUtil.absentIfEmpty(proto.getFamilyName()); this.profileFamilyName = OptionalUtil.absentIfEmpty(proto.getFamilyName());
this.profileKey = OptionalUtil.absentIfEmpty(proto.getProfileKey()); this.systemGivenName = OptionalUtil.absentIfEmpty(proto.getSystemGivenName());
this.username = OptionalUtil.absentIfEmpty(proto.getUsername()); this.systemFamilyName = OptionalUtil.absentIfEmpty(proto.getSystemFamilyName());
this.identityKey = OptionalUtil.absentIfEmpty(proto.getIdentityKey()); this.profileKey = OptionalUtil.absentIfEmpty(proto.getProfileKey());
this.username = OptionalUtil.absentIfEmpty(proto.getUsername());
this.identityKey = OptionalUtil.absentIfEmpty(proto.getIdentityKey());
} }
@Override @Override
@ -81,12 +85,20 @@ public final class SignalContactRecord implements SignalRecord {
diff.add("E164"); diff.add("E164");
} }
if (!Objects.equals(this.givenName, that.givenName)) { if (!Objects.equals(this.profileGivenName, that.profileGivenName)) {
diff.add("GivenName"); diff.add("ProfileGivenName");
} }
if (!Objects.equals(this.familyName, that.familyName)) { if (!Objects.equals(this.profileFamilyName, that.profileFamilyName)) {
diff.add("FamilyName"); diff.add("ProfileFamilyName");
}
if (!Objects.equals(this.systemGivenName, that.systemGivenName)) {
diff.add("SystemGivenName");
}
if (!Objects.equals(this.systemFamilyName, that.systemFamilyName)) {
diff.add("SystemFamilyName");
} }
if (!OptionalUtil.byteArrayEquals(this.profileKey, that.profileKey)) { if (!OptionalUtil.byteArrayEquals(this.profileKey, that.profileKey)) {
@ -167,12 +179,20 @@ public final class SignalContactRecord implements SignalRecord {
return e164; return e164;
} }
public Optional<String> getGivenName() { public Optional<String> getProfileGivenName() {
return givenName; return profileGivenName;
} }
public Optional<String> getFamilyName() { public Optional<String> getProfileFamilyName() {
return familyName; return profileFamilyName;
}
public Optional<String> getSystemGivenName() {
return systemGivenName;
}
public Optional<String> getSystemFamilyName() {
return systemFamilyName;
} }
public Optional<byte[]> getProfileKey() { public Optional<byte[]> getProfileKey() {
@ -274,16 +294,26 @@ public final class SignalContactRecord implements SignalRecord {
return this; return this;
} }
public Builder setGivenName(String givenName) { public Builder setProfileGivenName(String givenName) {
builder.setGivenName(givenName == null ? "" : givenName); builder.setGivenName(givenName == null ? "" : givenName);
return this; return this;
} }
public Builder setFamilyName(String familyName) { public Builder setProfileFamilyName(String familyName) {
builder.setFamilyName(familyName == null ? "" : familyName); builder.setFamilyName(familyName == null ? "" : familyName);
return this; return this;
} }
public Builder setSystemGivenName(String givenName) {
builder.setSystemGivenName(givenName == null ? "" : givenName);
return this;
}
public Builder setSystemFamilyName(String familyName) {
builder.setSystemFamilyName(familyName == null ? "" : familyName);
return this;
}
public Builder setProfileKey(byte[] profileKey) { public Builder setProfileKey(byte[] profileKey) {
builder.setProfileKey(profileKey == null ? ByteString.EMPTY : ByteString.copyFrom(profileKey)); builder.setProfileKey(profileKey == null ? ByteString.EMPTY : ByteString.copyFrom(profileKey));
return this; return this;

Wyświetl plik

@ -87,6 +87,8 @@ message ContactRecord {
uint64 mutedUntilTimestamp = 13; uint64 mutedUntilTimestamp = 13;
bool hideStory = 14; bool hideStory = 14;
uint64 unregisteredAtTimestamp = 16; uint64 unregisteredAtTimestamp = 16;
string systemGivenName = 17;
string systemFamilyName = 18;
bool hidden = 19; bool hidden = 19;
// NEXT ID: 20 // NEXT ID: 20
} }

Wyświetl plik

@ -2,7 +2,6 @@ package org.whispersystems.signalservice.api.storage;
import org.junit.Test; import org.junit.Test;
import org.whispersystems.signalservice.api.push.ServiceId; import org.whispersystems.signalservice.api.push.ServiceId;
import org.whispersystems.signalservice.api.push.SignalServiceAddress;
import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotEquals; import static org.junit.Assert.assertNotEquals;
@ -53,6 +52,6 @@ public class SignalContactRecordTest {
{ {
return new SignalContactRecord.Builder(byteArray(key), serviceId, null) return new SignalContactRecord.Builder(byteArray(key), serviceId, null)
.setE164(e164) .setE164(e164)
.setGivenName(givenName); .setProfileGivenName(givenName);
} }
} }