mirror of
https://github.com/signalapp/Signal-Android.git
synced 2026-02-21 10:17:56 +00:00
Add support for system names on the ContactRecord.
This commit is contained in:
@@ -925,6 +925,21 @@ open class RecipientDatabase(context: Context, databaseHelper: SignalDatabase) :
|
||||
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>) {
|
||||
val db = writableDatabase
|
||||
db.beginTransaction()
|
||||
@@ -3667,8 +3682,9 @@ open class RecipientDatabase(context: Context, databaseHelper: SignalDatabase) :
|
||||
|
||||
private fun getValuesForStorageContact(contact: SignalContactRecord, isInsert: Boolean): ContentValues {
|
||||
return ContentValues().apply {
|
||||
val profileName = ProfileName.fromParts(contact.givenName.orElse(null), contact.familyName.orElse(null))
|
||||
val username: String? = contact.username.orElse(null)
|
||||
val profileName = ProfileName.fromParts(contact.profileGivenName.orElse(null), contact.profileFamilyName.orElse(null))
|
||||
val systemName = ProfileName.fromParts(contact.systemGivenName.orElse(null), contact.systemFamilyName.orElse(null))
|
||||
val username = contact.username.orElse(null)
|
||||
|
||||
if (contact.serviceId.isValid) {
|
||||
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_FAMILY_NAME, profileName.familyName)
|
||||
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(USERNAME, if (TextUtils.isEmpty(username)) null else username)
|
||||
put(PROFILE_SHARING, if (contact.isProfileSharingEnabled) "1" else "0")
|
||||
|
||||
@@ -61,6 +61,7 @@ import org.thoughtcrime.securesms.migrations.StickerLaunchMigrationJob;
|
||||
import org.thoughtcrime.securesms.migrations.StickerMyDailyLifeMigrationJob;
|
||||
import org.thoughtcrime.securesms.migrations.StorageCapabilityMigrationJob;
|
||||
import org.thoughtcrime.securesms.migrations.StorageServiceMigrationJob;
|
||||
import org.thoughtcrime.securesms.migrations.StorageServiceSystemNameMigrationJob;
|
||||
import org.thoughtcrime.securesms.migrations.SyncDistributionListsMigrationJob;
|
||||
import org.thoughtcrime.securesms.migrations.TrimByLengthSettingsMigrationJob;
|
||||
import org.thoughtcrime.securesms.migrations.UserNotificationMigrationJob;
|
||||
@@ -221,6 +222,7 @@ public final class JobManagerFactories {
|
||||
put(StickerMyDailyLifeMigrationJob.KEY, new StickerMyDailyLifeMigrationJob.Factory());
|
||||
put(StorageCapabilityMigrationJob.KEY, new StorageCapabilityMigrationJob.Factory());
|
||||
put(StorageServiceMigrationJob.KEY, new StorageServiceMigrationJob.Factory());
|
||||
put(StorageServiceSystemNameMigrationJob.KEY, new StorageServiceSystemNameMigrationJob.Factory());
|
||||
put(TrimByLengthSettingsMigrationJob.KEY, new TrimByLengthSettingsMigrationJob.Factory());
|
||||
put(UserNotificationMigrationJob.KEY, new UserNotificationMigrationJob.Factory());
|
||||
put(UuidMigrationJob.KEY, new UuidMigrationJob.Factory());
|
||||
|
||||
@@ -108,9 +108,10 @@ public class ApplicationMigrations {
|
||||
static final int REFRESH_PNI_REGISTRATION_ID = 64;
|
||||
static final int KBS_MIGRATION_2 = 65;
|
||||
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
|
||||
@@ -476,6 +477,10 @@ public class ApplicationMigrations {
|
||||
jobs.put(Version.PNI_2, new PniMigrationJob());
|
||||
}
|
||||
|
||||
if (lastSeenVersion < Version.SYSTEM_NAME_SYNC) {
|
||||
jobs.put(Version.SYSTEM_NAME_SYNC, new StorageServiceSystemNameMigrationJob());
|
||||
}
|
||||
|
||||
return jobs;
|
||||
}
|
||||
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,7 +1,5 @@
|
||||
package org.thoughtcrime.securesms.storage;
|
||||
|
||||
import android.content.Context;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
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.PNI;
|
||||
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.util.OptionalUtil;
|
||||
import org.whispersystems.signalservice.internal.storage.protos.ContactRecord.IdentityState;
|
||||
@@ -122,15 +119,15 @@ public class ContactRecordProcessor extends DefaultStorageRecordProcessor<Signal
|
||||
remote = remote.withoutPni();
|
||||
}
|
||||
|
||||
String givenName;
|
||||
String familyName;
|
||||
String profileGivenName;
|
||||
String profileFamilyName;
|
||||
|
||||
if (remote.getGivenName().isPresent() || remote.getFamilyName().isPresent()) {
|
||||
givenName = remote.getGivenName().orElse("");
|
||||
familyName = remote.getFamilyName().orElse("");
|
||||
if (remote.getProfileGivenName().isPresent() || remote.getProfileFamilyName().isPresent()) {
|
||||
profileGivenName = remote.getProfileGivenName().orElse("");
|
||||
profileFamilyName = remote.getProfileFamilyName().orElse("");
|
||||
} else {
|
||||
givenName = local.getGivenName().orElse("");
|
||||
familyName = local.getFamilyName().orElse("");
|
||||
profileGivenName = local.getProfileGivenName().orElse("");
|
||||
profileFamilyName = local.getProfileFamilyName().orElse("");
|
||||
}
|
||||
|
||||
IdentityState identityState;
|
||||
@@ -198,8 +195,10 @@ public class ContactRecordProcessor extends DefaultStorageRecordProcessor<Signal
|
||||
boolean hideStory = remote.shouldHideStory();
|
||||
long unregisteredTimestamp = remote.getUnregisteredTimestamp();
|
||||
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);
|
||||
boolean matchesLocal = doParamsMatch(local, 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("");
|
||||
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) {
|
||||
return remote;
|
||||
@@ -209,8 +208,10 @@ public class ContactRecordProcessor extends DefaultStorageRecordProcessor<Signal
|
||||
return new SignalContactRecord.Builder(keyGenerator.generate(), serviceId, unknownFields)
|
||||
.setE164(e164)
|
||||
.setPni(pni)
|
||||
.setGivenName(givenName)
|
||||
.setFamilyName(familyName)
|
||||
.setProfileGivenName(profileGivenName)
|
||||
.setProfileFamilyName(profileFamilyName)
|
||||
.setSystemGivenName(systemGivenName)
|
||||
.setSystemFamilyName(systemFamilyName)
|
||||
.setProfileKey(profileKey)
|
||||
.setUsername(username)
|
||||
.setIdentityState(identityState)
|
||||
@@ -254,8 +255,10 @@ public class ContactRecordProcessor extends DefaultStorageRecordProcessor<Signal
|
||||
@NonNull ServiceId serviceId,
|
||||
@Nullable PNI pni,
|
||||
@Nullable String e164,
|
||||
@NonNull String givenName,
|
||||
@NonNull String familyName,
|
||||
@NonNull String profileGivenName,
|
||||
@NonNull String profileFamilyName,
|
||||
@NonNull String systemGivenName,
|
||||
@NonNull String systemFamilyName,
|
||||
@Nullable byte[] profileKey,
|
||||
@NonNull String username,
|
||||
@Nullable IdentityState identityState,
|
||||
@@ -269,23 +272,25 @@ public class ContactRecordProcessor extends DefaultStorageRecordProcessor<Signal
|
||||
long unregisteredTimestamp,
|
||||
boolean hidden)
|
||||
{
|
||||
return Arrays.equals(contact.serializeUnknownFields(), unknownFields) &&
|
||||
Objects.equals(contact.getServiceId(), serviceId) &&
|
||||
Objects.equals(contact.getPni().orElse(null), pni) &&
|
||||
Objects.equals(contact.getNumber().orElse(null), e164) &&
|
||||
Objects.equals(contact.getGivenName().orElse(""), givenName) &&
|
||||
Objects.equals(contact.getFamilyName().orElse(""), familyName) &&
|
||||
Arrays.equals(contact.getProfileKey().orElse(null), profileKey) &&
|
||||
Objects.equals(contact.getUsername().orElse(""), username) &&
|
||||
Objects.equals(contact.getIdentityState(), identityState) &&
|
||||
Arrays.equals(contact.getIdentityKey().orElse(null), identityKey) &&
|
||||
contact.isBlocked() == blocked &&
|
||||
contact.isProfileSharingEnabled() == profileSharing &&
|
||||
contact.isArchived() == archived &&
|
||||
contact.isForcedUnread() == forcedUnread &&
|
||||
contact.getMuteUntil() == muteUntil &&
|
||||
contact.shouldHideStory() == hideStory &&
|
||||
contact.getUnregisteredTimestamp() == unregisteredTimestamp &&
|
||||
return Arrays.equals(contact.serializeUnknownFields(), unknownFields) &&
|
||||
Objects.equals(contact.getServiceId(), serviceId) &&
|
||||
Objects.equals(contact.getPni().orElse(null), pni) &&
|
||||
Objects.equals(contact.getNumber().orElse(null), e164) &&
|
||||
Objects.equals(contact.getProfileGivenName().orElse(""), profileGivenName) &&
|
||||
Objects.equals(contact.getProfileFamilyName().orElse(""), profileFamilyName) &&
|
||||
Objects.equals(contact.getSystemGivenName().orElse(""), systemGivenName) &&
|
||||
Objects.equals(contact.getSystemFamilyName().orElse(""), systemFamilyName) &&
|
||||
Arrays.equals(contact.getProfileKey().orElse(null), profileKey) &&
|
||||
Objects.equals(contact.getUsername().orElse(""), username) &&
|
||||
Objects.equals(contact.getIdentityState(), identityState) &&
|
||||
Arrays.equals(contact.getIdentityKey().orElse(null), identityKey) &&
|
||||
contact.isBlocked() == blocked &&
|
||||
contact.isProfileSharingEnabled() == profileSharing &&
|
||||
contact.isArchived() == archived &&
|
||||
contact.isForcedUnread() == forcedUnread &&
|
||||
contact.getMuteUntil() == muteUntil &&
|
||||
contact.shouldHideStory() == hideStory &&
|
||||
contact.getUnregisteredTimestamp() == unregisteredTimestamp &&
|
||||
contact.isHidden() == hidden;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -11,15 +11,12 @@ import org.thoughtcrime.securesms.database.IdentityDatabase;
|
||||
import org.thoughtcrime.securesms.database.RecipientDatabase;
|
||||
import org.thoughtcrime.securesms.database.SignalDatabase;
|
||||
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.RecipientRecord;
|
||||
import org.thoughtcrime.securesms.dependencies.ApplicationDependencies;
|
||||
import org.thoughtcrime.securesms.groups.GroupId;
|
||||
import org.thoughtcrime.securesms.keyvalue.PhoneNumberPrivacyValues;
|
||||
import org.thoughtcrime.securesms.recipients.Recipient;
|
||||
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.SignalServiceAddress;
|
||||
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.GroupV2Record;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
@@ -116,8 +112,10 @@ public final class StorageSyncModels {
|
||||
.setE164(recipient.getE164())
|
||||
.setPni(recipient.getPni())
|
||||
.setProfileKey(recipient.getProfileKey())
|
||||
.setGivenName(recipient.getProfileName().getGivenName())
|
||||
.setFamilyName(recipient.getProfileName().getFamilyName())
|
||||
.setProfileGivenName(recipient.getProfileName().getGivenName())
|
||||
.setProfileFamilyName(recipient.getProfileName().getFamilyName())
|
||||
.setSystemGivenName(recipient.getSystemProfileName().getGivenName())
|
||||
.setSystemFamilyName(recipient.getSystemProfileName().getFamilyName())
|
||||
.setBlocked(recipient.isBlocked())
|
||||
.setProfileSharingEnabled(recipient.isProfileSharing() || recipient.getSystemContactUri() != null)
|
||||
.setIdentityKey(recipient.getSyncExtras().getIdentityKey())
|
||||
|
||||
Reference in New Issue
Block a user