mirror of
https://github.com/signalapp/Signal-Android.git
synced 2026-03-02 07:23:38 +00:00
Add backup support for contact nicknames and notes.
This commit is contained in:
@@ -46,6 +46,9 @@ fun RecipientTable.getContactsForBackup(selfId: Long): ContactArchiveExporter {
|
||||
"${RecipientTable.TABLE_NAME}.${RecipientTable.PROFILE_GIVEN_NAME}",
|
||||
"${RecipientTable.TABLE_NAME}.${RecipientTable.PROFILE_FAMILY_NAME}",
|
||||
"${RecipientTable.TABLE_NAME}.${RecipientTable.PROFILE_JOINED_NAME}",
|
||||
"${RecipientTable.TABLE_NAME}.${RecipientTable.NICKNAME_GIVEN_NAME}",
|
||||
"${RecipientTable.TABLE_NAME}.${RecipientTable.NICKNAME_FAMILY_NAME}",
|
||||
"${RecipientTable.TABLE_NAME}.${RecipientTable.NOTE}",
|
||||
"${RecipientTable.TABLE_NAME}.${RecipientTable.MUTE_UNTIL}",
|
||||
"${RecipientTable.TABLE_NAME}.${RecipientTable.CHAT_COLORS}",
|
||||
"${RecipientTable.TABLE_NAME}.${RecipientTable.CUSTOM_CHAT_COLORS_ID}",
|
||||
|
||||
@@ -673,36 +673,34 @@ private fun BackupMessageRecord.toRemotePaymentNotificationUpdate(db: SignalData
|
||||
}
|
||||
}
|
||||
|
||||
private fun BackupMessageRecord.toRemoteSharedContacts(attachments: List<DatabaseAttachment>?): List<Contact>? {
|
||||
private fun BackupMessageRecord.toRemoteSharedContact(attachments: List<DatabaseAttachment>?): Contact? {
|
||||
if (this.sharedContacts.isNullOrEmpty()) {
|
||||
return emptyList()
|
||||
return null
|
||||
}
|
||||
|
||||
val attachmentIdMap: Map<AttachmentId, DatabaseAttachment> = attachments?.associateBy { it.attachmentId } ?: emptyMap()
|
||||
|
||||
return try {
|
||||
val contacts: MutableList<Contact> = LinkedList()
|
||||
val jsonContacts = JSONArray(sharedContacts)
|
||||
|
||||
for (i in 0 until jsonContacts.length()) {
|
||||
val contact: Contact = Contact.deserialize(jsonContacts.getJSONObject(i).toString())
|
||||
|
||||
if (contact.avatar != null && contact.avatar!!.attachmentId != null) {
|
||||
val attachment = attachmentIdMap[contact.avatar!!.attachmentId]
|
||||
|
||||
val updatedAvatar = Contact.Avatar(
|
||||
contact.avatar!!.attachmentId,
|
||||
attachment,
|
||||
contact.avatar!!.isProfile
|
||||
)
|
||||
|
||||
contacts += Contact(contact, updatedAvatar)
|
||||
} else {
|
||||
contacts += contact
|
||||
}
|
||||
if (jsonContacts.length() == 0) {
|
||||
return null
|
||||
}
|
||||
|
||||
contacts
|
||||
val contact: Contact = Contact.deserialize(jsonContacts.getJSONObject(0).toString())
|
||||
|
||||
return if (contact.avatar != null && contact.avatar!!.attachmentId != null) {
|
||||
val attachment = attachmentIdMap[contact.avatar!!.attachmentId]
|
||||
|
||||
val updatedAvatar = Contact.Avatar(
|
||||
contact.avatar!!.attachmentId,
|
||||
attachment,
|
||||
contact.avatar!!.isProfile
|
||||
)
|
||||
|
||||
Contact(contact, updatedAvatar)
|
||||
} else {
|
||||
contact
|
||||
}
|
||||
} catch (e: JSONException) {
|
||||
Log.w(TAG, ExportSkips.failedToParseSharedContact(this.dateSent), e)
|
||||
null
|
||||
@@ -768,28 +766,28 @@ private fun BackupMessageRecord.toRemoteViewOnceMessage(mediaArchiveEnabled: Boo
|
||||
}
|
||||
|
||||
private fun BackupMessageRecord.toRemoteContactMessage(mediaArchiveEnabled: Boolean, reactionRecords: List<ReactionRecord>?, attachments: List<DatabaseAttachment>?): ContactMessage? {
|
||||
val sharedContacts = toRemoteSharedContacts(attachments) ?: return null
|
||||
val sharedContact = toRemoteSharedContact(attachments) ?: return null
|
||||
|
||||
val contacts = sharedContacts.map {
|
||||
ContactAttachment(
|
||||
name = it.name.toRemote(),
|
||||
avatar = (it.avatar?.attachment as? DatabaseAttachment)?.toRemoteMessageAttachment(mediaArchiveEnabled)?.pointer,
|
||||
organization = it.organization ?: "",
|
||||
number = it.phoneNumbers.map { phone ->
|
||||
return ContactMessage(
|
||||
contact = ContactAttachment(
|
||||
name = sharedContact.name.toRemote(),
|
||||
avatar = (sharedContact.avatar?.attachment as? DatabaseAttachment)?.toRemoteMessageAttachment(mediaArchiveEnabled)?.pointer,
|
||||
organization = sharedContact.organization ?: "",
|
||||
number = sharedContact.phoneNumbers.map { phone ->
|
||||
ContactAttachment.Phone(
|
||||
value_ = phone.number,
|
||||
type = phone.type.toRemote(),
|
||||
label = phone.label ?: ""
|
||||
)
|
||||
},
|
||||
email = it.emails.map { email ->
|
||||
email = sharedContact.emails.map { email ->
|
||||
ContactAttachment.Email(
|
||||
value_ = email.email,
|
||||
label = email.label ?: "",
|
||||
type = email.type.toRemote()
|
||||
)
|
||||
},
|
||||
address = it.postalAddresses.map { address ->
|
||||
address = sharedContact.postalAddresses.map { address ->
|
||||
ContactAttachment.PostalAddress(
|
||||
type = address.type.toRemote(),
|
||||
label = address.label ?: "",
|
||||
@@ -802,10 +800,7 @@ private fun BackupMessageRecord.toRemoteContactMessage(mediaArchiveEnabled: Bool
|
||||
country = address.country ?: ""
|
||||
)
|
||||
}
|
||||
)
|
||||
}
|
||||
return ContactMessage(
|
||||
contact = contacts,
|
||||
),
|
||||
reactions = reactionRecords.toRemote()
|
||||
)
|
||||
}
|
||||
|
||||
@@ -76,6 +76,8 @@ class ContactArchiveExporter(private val cursor: Cursor, private val selfId: Lon
|
||||
.hideStory(RecipientTableCursorUtil.getExtras(cursor)?.hideStory() ?: false)
|
||||
.identityKey(cursor.requireString(IdentityTable.IDENTITY_KEY)?.let { Base64.decode(it).toByteString() })
|
||||
.identityState(cursor.optionalInt(IdentityTable.VERIFIED).map { IdentityTable.VerifiedStatus.forState(it) }.orElse(IdentityTable.VerifiedStatus.DEFAULT).toRemote())
|
||||
.note(cursor.requireString(RecipientTable.NOTE) ?: "")
|
||||
.nickname(cursor.readNickname())
|
||||
|
||||
val registeredState = RecipientTable.RegisteredState.fromId(cursor.requireInt(RecipientTable.REGISTERED))
|
||||
if (registeredState == RecipientTable.RegisteredState.REGISTERED) {
|
||||
@@ -95,6 +97,20 @@ class ContactArchiveExporter(private val cursor: Cursor, private val selfId: Lon
|
||||
}
|
||||
}
|
||||
|
||||
private fun Cursor.readNickname(): Contact.Name? {
|
||||
val given = this.requireString(RecipientTable.NICKNAME_GIVEN_NAME)
|
||||
val family = this.requireString(RecipientTable.NICKNAME_FAMILY_NAME)
|
||||
|
||||
if (given.isNullOrEmpty()) {
|
||||
return null
|
||||
}
|
||||
|
||||
return Contact.Name(
|
||||
given = given,
|
||||
family = family ?: ""
|
||||
)
|
||||
}
|
||||
|
||||
private fun Recipient.HiddenState.toRemote(): Contact.Visibility {
|
||||
return when (this) {
|
||||
Recipient.HiddenState.NOT_HIDDEN -> return Contact.Visibility.VISIBLE
|
||||
|
||||
@@ -310,7 +310,7 @@ class ChatItemArchiveImporter(
|
||||
}
|
||||
|
||||
if (this.contactMessage != null) {
|
||||
val contacts = this.contactMessage.contact.map { backupContact ->
|
||||
val contact = this.contactMessage.contact?.let { backupContact ->
|
||||
Contact(
|
||||
backupContact.name.toLocal(),
|
||||
backupContact.organization,
|
||||
@@ -345,18 +345,18 @@ class ChatItemArchiveImporter(
|
||||
)
|
||||
}
|
||||
|
||||
val contactAttachments = contacts.mapNotNull { it.avatarAttachment }
|
||||
if (contacts.isNotEmpty()) {
|
||||
if (contact != null) {
|
||||
val contactAttachment: Attachment? = contact.avatarAttachment
|
||||
followUp = { messageRowId ->
|
||||
val attachmentMap = if (contactAttachments.isNotEmpty()) {
|
||||
SignalDatabase.attachments.insertAttachmentsForMessage(messageRowId, contactAttachments, emptyList())
|
||||
val attachmentMap = if (contactAttachment != null) {
|
||||
SignalDatabase.attachments.insertAttachmentsForMessage(messageRowId, listOf(contactAttachment), emptyList())
|
||||
} else {
|
||||
emptyMap()
|
||||
}
|
||||
db.update(
|
||||
MessageTable.TABLE_NAME,
|
||||
contentValuesOf(
|
||||
MessageTable.SHARED_CONTACTS to SignalDatabase.messages.getSerializedSharedContacts(attachmentMap, contacts)
|
||||
MessageTable.SHARED_CONTACTS to SignalDatabase.messages.getSerializedSharedContacts(attachmentMap, listOf(contact))
|
||||
),
|
||||
"${MessageTable.ID} = ?",
|
||||
SqlUtil.buildArgs(messageRowId)
|
||||
|
||||
@@ -49,7 +49,10 @@ object ContactArchiveImporter {
|
||||
RecipientTable.PROFILE_KEY to if (profileKey == null) null else Base64.encodeWithPadding(profileKey),
|
||||
RecipientTable.PROFILE_SHARING to contact.profileSharing.toInt(),
|
||||
RecipientTable.USERNAME to contact.username,
|
||||
RecipientTable.EXTRAS to contact.toLocalExtras().encode()
|
||||
RecipientTable.EXTRAS to contact.toLocalExtras().encode(),
|
||||
RecipientTable.NOTE to contact.note,
|
||||
RecipientTable.NICKNAME_GIVEN_NAME to contact.nickname?.given,
|
||||
RecipientTable.NICKNAME_FAMILY_NAME to contact.nickname?.family
|
||||
)
|
||||
|
||||
if (contact.registered != null) {
|
||||
|
||||
Reference in New Issue
Block a user