mirror of
https://github.com/signalapp/Signal-Android.git
synced 2026-02-26 20:55:10 +00:00
Update backup proto with subscriber and recipient changes.
This commit is contained in:
@@ -38,7 +38,7 @@ fun CallTable.restoreCallLogFromBackup(call: AdHocCall, backupState: BackupState
|
||||
CallTable.TYPE to CallTable.Type.serialize(CallTable.Type.AD_HOC_CALL),
|
||||
CallTable.DIRECTION to CallTable.Direction.serialize(CallTable.Direction.OUTGOING),
|
||||
CallTable.EVENT to CallTable.Event.serialize(event),
|
||||
CallTable.TIMESTAMP to call.startedCallTimestamp
|
||||
CallTable.TIMESTAMP to call.callTimestamp
|
||||
)
|
||||
|
||||
writableDatabase.insert(CallTable.TABLE_NAME, SQLiteDatabase.CONFLICT_IGNORE, values)
|
||||
@@ -64,7 +64,7 @@ class CallLogIterator(private val cursor: Cursor) : Iterator<AdHocCall?>, Closea
|
||||
callId = callId,
|
||||
recipientId = cursor.requireLong(CallTable.PEER),
|
||||
state = AdHocCall.State.GENERIC,
|
||||
startedCallTimestamp = cursor.requireLong(CallTable.TIMESTAMP)
|
||||
callTimestamp = cursor.requireLong(CallTable.TIMESTAMP)
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
@@ -538,6 +538,7 @@ class ChatItemImportInserter(
|
||||
SimpleChatUpdate.Type.BAD_DECRYPT -> MessageTypes.BAD_DECRYPT_TYPE or typeWithoutBase
|
||||
SimpleChatUpdate.Type.PAYMENTS_ACTIVATED -> MessageTypes.SPECIAL_TYPE_PAYMENTS_ACTIVATED or typeWithoutBase
|
||||
SimpleChatUpdate.Type.PAYMENT_ACTIVATION_REQUEST -> MessageTypes.SPECIAL_TYPE_PAYMENTS_ACTIVATE_REQUEST or typeWithoutBase
|
||||
SimpleChatUpdate.Type.UNSUPPORTED_PROTOCOL_MESSAGE -> MessageTypes.UNSUPPORTED_MESSAGE_TYPE or typeWithoutBase
|
||||
}
|
||||
}
|
||||
updateMessage.expirationTimerChange != null -> {
|
||||
|
||||
@@ -15,6 +15,8 @@ import org.signal.core.util.requireNonNullString
|
||||
import org.signal.core.util.requireObject
|
||||
import org.signal.core.util.select
|
||||
import org.thoughtcrime.securesms.backup.v2.BackupState
|
||||
import org.thoughtcrime.securesms.backup.v2.proto.DistributionList
|
||||
import org.thoughtcrime.securesms.backup.v2.proto.DistributionListItem
|
||||
import org.thoughtcrime.securesms.database.DistributionListTables
|
||||
import org.thoughtcrime.securesms.database.SignalDatabase
|
||||
import org.thoughtcrime.securesms.database.model.DistributionListId
|
||||
@@ -60,19 +62,28 @@ fun DistributionListTables.getAllForBackup(): List<BackupRecipient> {
|
||||
.map { recipient ->
|
||||
BackupRecipient(
|
||||
id = recipient.id.toLong(),
|
||||
distributionList = BackupDistributionList(
|
||||
name = recipient.record.name,
|
||||
distributionId = recipient.record.distributionId.asUuid().toByteArray().toByteString(),
|
||||
allowReplies = recipient.record.allowsReplies,
|
||||
deletionTimestamp = recipient.record.deletedAtTimestamp,
|
||||
privacyMode = recipient.record.privacyMode.toBackupPrivacyMode(),
|
||||
memberRecipientIds = recipient.record.members.map { it.toLong() }
|
||||
)
|
||||
distributionList = if (recipient.record.deletedAtTimestamp != 0L) {
|
||||
DistributionListItem(
|
||||
distributionId = recipient.record.distributionId.asUuid().toByteArray().toByteString(),
|
||||
deletionTimestamp = recipient.record.deletedAtTimestamp
|
||||
)
|
||||
} else {
|
||||
DistributionListItem(
|
||||
distributionId = recipient.record.distributionId.asUuid().toByteArray().toByteString(),
|
||||
distributionList = DistributionList(
|
||||
name = recipient.record.name,
|
||||
allowReplies = recipient.record.allowsReplies,
|
||||
privacyMode = recipient.record.privacyMode.toBackupPrivacyMode(),
|
||||
memberRecipientIds = recipient.record.members.map { it.toLong() }
|
||||
)
|
||||
)
|
||||
}
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
fun DistributionListTables.restoreFromBackup(dlist: BackupDistributionList, backupState: BackupState): RecipientId {
|
||||
fun DistributionListTables.restoreFromBackup(dlistItem: DistributionListItem, backupState: BackupState): RecipientId? {
|
||||
val dlist = dlistItem.distributionList ?: return null
|
||||
val members: List<RecipientId> = dlist.memberRecipientIds
|
||||
.mapNotNull { backupState.backupToLocalRecipientId[it] }
|
||||
|
||||
@@ -83,9 +94,9 @@ fun DistributionListTables.restoreFromBackup(dlist: BackupDistributionList, back
|
||||
val dlistId = this.createList(
|
||||
name = dlist.name,
|
||||
members = members,
|
||||
distributionId = DistributionId.from(UuidUtil.fromByteString(dlist.distributionId)),
|
||||
distributionId = DistributionId.from(UuidUtil.fromByteString(dlistItem.distributionId)),
|
||||
allowsReplies = dlist.allowReplies,
|
||||
deletionTimestamp = dlist.deletionTimestamp,
|
||||
deletionTimestamp = dlistItem.deletionTimestamp ?: 0,
|
||||
storageId = null,
|
||||
privacyMode = dlist.privacyMode.toLocalPrivacyMode()
|
||||
)!!
|
||||
|
||||
@@ -7,6 +7,7 @@ package org.thoughtcrime.securesms.backup.v2.database
|
||||
|
||||
import android.content.ContentValues
|
||||
import android.database.Cursor
|
||||
import androidx.core.content.contentValuesOf
|
||||
import okio.ByteString.Companion.toByteString
|
||||
import org.signal.core.util.Base64
|
||||
import org.signal.core.util.SqlUtil
|
||||
@@ -175,23 +176,30 @@ fun RecipientTable.restoreContactFromBackup(contact: Contact): RecipientId {
|
||||
)
|
||||
|
||||
val profileKey = contact.profileKey?.toByteArray()
|
||||
val values = contentValuesOf(
|
||||
RecipientTable.BLOCKED to contact.blocked,
|
||||
RecipientTable.HIDDEN to (contact.visibility == Contact.Visibility.HIDDEN),
|
||||
RecipientTable.TYPE to RecipientTable.RecipientType.INDIVIDUAL.id,
|
||||
RecipientTable.PROFILE_FAMILY_NAME to contact.profileFamilyName.nullIfBlank(),
|
||||
RecipientTable.PROFILE_GIVEN_NAME to contact.profileGivenName.nullIfBlank(),
|
||||
RecipientTable.PROFILE_JOINED_NAME to ProfileName.fromParts(contact.profileGivenName.nullIfBlank(), contact.profileFamilyName.nullIfBlank()).toString().nullIfBlank(),
|
||||
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()
|
||||
)
|
||||
|
||||
if (contact.registered != null) {
|
||||
values.put(RecipientTable.UNREGISTERED_TIMESTAMP, 0L)
|
||||
values.put(RecipientTable.REGISTERED, RecipientTable.RegisteredState.REGISTERED.id)
|
||||
} else if (contact.notRegistered != null) {
|
||||
values.put(RecipientTable.UNREGISTERED_TIMESTAMP, contact.notRegistered.unregisteredTimestamp)
|
||||
values.put(RecipientTable.REGISTERED, RecipientTable.RegisteredState.NOT_REGISTERED.id)
|
||||
}
|
||||
|
||||
writableDatabase
|
||||
.update(RecipientTable.TABLE_NAME)
|
||||
.values(
|
||||
RecipientTable.BLOCKED to contact.blocked,
|
||||
RecipientTable.HIDDEN to contact.hidden,
|
||||
RecipientTable.TYPE to RecipientTable.RecipientType.INDIVIDUAL.id,
|
||||
RecipientTable.PROFILE_FAMILY_NAME to contact.profileFamilyName.nullIfBlank(),
|
||||
RecipientTable.PROFILE_GIVEN_NAME to contact.profileGivenName.nullIfBlank(),
|
||||
RecipientTable.PROFILE_JOINED_NAME to ProfileName.fromParts(contact.profileGivenName.nullIfBlank(), contact.profileFamilyName.nullIfBlank()).toString().nullIfBlank(),
|
||||
RecipientTable.PROFILE_KEY to if (profileKey == null) null else Base64.encodeWithPadding(profileKey),
|
||||
RecipientTable.PROFILE_SHARING to contact.profileSharing.toInt(),
|
||||
RecipientTable.REGISTERED to contact.registered.toLocalRegisteredState().id,
|
||||
RecipientTable.USERNAME to contact.username,
|
||||
RecipientTable.UNREGISTERED_TIMESTAMP to contact.unregisteredTimestamp,
|
||||
RecipientTable.EXTRAS to contact.toLocalExtras().encode()
|
||||
)
|
||||
.values(values)
|
||||
.where("${RecipientTable.ID} = ?", id)
|
||||
.run()
|
||||
|
||||
@@ -418,23 +426,28 @@ class BackupContactIterator(private val cursor: Cursor, private val selfId: Long
|
||||
return null
|
||||
}
|
||||
|
||||
val contactBuilder = Contact.Builder()
|
||||
.aci(aci?.rawUuid?.toByteArray()?.toByteString())
|
||||
.pni(pni?.rawUuid?.toByteArray()?.toByteString())
|
||||
.username(cursor.requireString(RecipientTable.USERNAME))
|
||||
.e164(cursor.requireString(RecipientTable.E164)?.e164ToLong())
|
||||
.blocked(cursor.requireBoolean(RecipientTable.BLOCKED))
|
||||
.visibility(if (cursor.requireBoolean(RecipientTable.HIDDEN)) Contact.Visibility.HIDDEN else Contact.Visibility.VISIBLE)
|
||||
.profileKey(if (profileKey != null) Base64.decode(profileKey).toByteString() else null)
|
||||
.profileSharing(cursor.requireBoolean(RecipientTable.PROFILE_SHARING))
|
||||
.profileGivenName(cursor.requireString(RecipientTable.PROFILE_GIVEN_NAME).nullIfBlank())
|
||||
.profileFamilyName(cursor.requireString(RecipientTable.PROFILE_FAMILY_NAME).nullIfBlank())
|
||||
.hideStory(extras?.hideStory() ?: false)
|
||||
|
||||
if (registeredState == RecipientTable.RegisteredState.REGISTERED) {
|
||||
contactBuilder.registered = Contact.Registered()
|
||||
} else {
|
||||
contactBuilder.notRegistered = Contact.NotRegistered(unregisteredTimestamp = cursor.requireLong(RecipientTable.UNREGISTERED_TIMESTAMP))
|
||||
}
|
||||
|
||||
return BackupRecipient(
|
||||
id = id,
|
||||
contact = Contact(
|
||||
aci = aci?.rawUuid?.toByteArray()?.toByteString(),
|
||||
pni = pni?.rawUuid?.toByteArray()?.toByteString(),
|
||||
username = cursor.requireString(RecipientTable.USERNAME),
|
||||
e164 = cursor.requireString(RecipientTable.E164)?.e164ToLong(),
|
||||
blocked = cursor.requireBoolean(RecipientTable.BLOCKED),
|
||||
hidden = cursor.requireBoolean(RecipientTable.HIDDEN),
|
||||
registered = registeredState.toContactRegisteredState(),
|
||||
unregisteredTimestamp = cursor.requireLong(RecipientTable.UNREGISTERED_TIMESTAMP),
|
||||
profileKey = if (profileKey != null) Base64.decode(profileKey).toByteString() else null,
|
||||
profileSharing = cursor.requireBoolean(RecipientTable.PROFILE_SHARING),
|
||||
profileGivenName = cursor.requireString(RecipientTable.PROFILE_GIVEN_NAME).nullIfBlank(),
|
||||
profileFamilyName = cursor.requireString(RecipientTable.PROFILE_FAMILY_NAME).nullIfBlank(),
|
||||
hideStory = extras?.hideStory() ?: false
|
||||
)
|
||||
contact = contactBuilder.build()
|
||||
)
|
||||
}
|
||||
|
||||
@@ -489,22 +502,6 @@ private fun String.e164ToLong(): Long? {
|
||||
return fixed.toLongOrNull()
|
||||
}
|
||||
|
||||
private fun RecipientTable.RegisteredState.toContactRegisteredState(): Contact.Registered {
|
||||
return when (this) {
|
||||
RecipientTable.RegisteredState.REGISTERED -> Contact.Registered.REGISTERED
|
||||
RecipientTable.RegisteredState.NOT_REGISTERED -> Contact.Registered.NOT_REGISTERED
|
||||
RecipientTable.RegisteredState.UNKNOWN -> Contact.Registered.UNKNOWN
|
||||
}
|
||||
}
|
||||
|
||||
private fun Contact.Registered.toLocalRegisteredState(): RecipientTable.RegisteredState {
|
||||
return when (this) {
|
||||
Contact.Registered.REGISTERED -> RecipientTable.RegisteredState.REGISTERED
|
||||
Contact.Registered.NOT_REGISTERED -> RecipientTable.RegisteredState.NOT_REGISTERED
|
||||
Contact.Registered.UNKNOWN -> RecipientTable.RegisteredState.UNKNOWN
|
||||
}
|
||||
}
|
||||
|
||||
private fun GroupTable.ShowAsStoryState.toGroupStorySendMode(): Group.StorySendMode {
|
||||
return when (this) {
|
||||
GroupTable.ShowAsStoryState.ALWAYS -> Group.StorySendMode.ENABLED
|
||||
|
||||
@@ -49,10 +49,7 @@ object AccountDataProcessor {
|
||||
givenName = self.profileName.givenName,
|
||||
familyName = self.profileName.familyName,
|
||||
avatarUrlPath = self.profileAvatar ?: "",
|
||||
subscriptionManuallyCancelled = InAppPaymentsRepository.isUserManuallyCancelled(InAppPaymentSubscriberRecord.Type.DONATION),
|
||||
username = self.username.getOrNull(),
|
||||
subscriberId = subscriber?.subscriberId?.bytes?.toByteString() ?: defaultAccountRecord.subscriberId,
|
||||
subscriberCurrencyCode = subscriber?.currency?.currencyCode ?: defaultAccountRecord.subscriberCurrencyCode,
|
||||
accountSettings = AccountData.AccountSettings(
|
||||
storyViewReceiptsEnabled = SignalStore.storyValues().viewedReceiptsEnabled,
|
||||
typingIndicators = TextSecurePreferences.isTypingIndicatorsEnabled(context),
|
||||
@@ -71,6 +68,11 @@ object AccountDataProcessor {
|
||||
displayBadgesOnProfile = SignalStore.donationsValues().getDisplayBadgesOnProfile(),
|
||||
hasSeenGroupStoryEducationSheet = SignalStore.storyValues().userHasSeenGroupStoryEducationSheet,
|
||||
hasCompletedUsernameOnboarding = SignalStore.uiHints().hasCompletedUsernameOnboarding()
|
||||
),
|
||||
donationSubscriberData = AccountData.SubscriberData(
|
||||
subscriberId = subscriber?.subscriberId?.bytes?.toByteString() ?: defaultAccountRecord.subscriberId,
|
||||
currencyCode = subscriber?.currency?.currencyCode ?: defaultAccountRecord.subscriberCurrencyCode,
|
||||
manuallyCancelled = InAppPaymentsRepository.isUserManuallyCancelled(InAppPaymentSubscriberRecord.Type.DONATION)
|
||||
)
|
||||
)
|
||||
)
|
||||
@@ -103,23 +105,25 @@ object AccountDataProcessor {
|
||||
SignalStore.storyValues().userHasSeenGroupStoryEducationSheet = settings.hasSeenGroupStoryEducationSheet
|
||||
SignalStore.storyValues().viewedReceiptsEnabled = settings.storyViewReceiptsEnabled ?: settings.readReceipts
|
||||
|
||||
if (accountData.subscriberId.size > 0) {
|
||||
val remoteSubscriberId = SubscriberId.fromBytes(accountData.subscriberId.toByteArray())
|
||||
val localSubscriber = InAppPaymentsRepository.getSubscriber(InAppPaymentSubscriberRecord.Type.DONATION)
|
||||
if (accountData.donationSubscriberData != null) {
|
||||
if (accountData.donationSubscriberData.subscriberId.size > 0) {
|
||||
val remoteSubscriberId = SubscriberId.fromBytes(accountData.donationSubscriberData.subscriberId.toByteArray())
|
||||
val localSubscriber = InAppPaymentsRepository.getSubscriber(InAppPaymentSubscriberRecord.Type.DONATION)
|
||||
|
||||
val subscriber = InAppPaymentSubscriberRecord(
|
||||
remoteSubscriberId,
|
||||
Currency.getInstance(accountData.subscriberCurrencyCode),
|
||||
InAppPaymentSubscriberRecord.Type.DONATION,
|
||||
localSubscriber?.requiresCancel ?: false,
|
||||
InAppPaymentsRepository.getLatestPaymentMethodType(InAppPaymentSubscriberRecord.Type.DONATION)
|
||||
)
|
||||
val subscriber = InAppPaymentSubscriberRecord(
|
||||
remoteSubscriberId,
|
||||
Currency.getInstance(accountData.donationSubscriberData.currencyCode),
|
||||
InAppPaymentSubscriberRecord.Type.DONATION,
|
||||
localSubscriber?.requiresCancel ?: accountData.donationSubscriberData.manuallyCancelled,
|
||||
InAppPaymentsRepository.getLatestPaymentMethodType(InAppPaymentSubscriberRecord.Type.DONATION)
|
||||
)
|
||||
|
||||
InAppPaymentsRepository.setSubscriber(subscriber)
|
||||
}
|
||||
InAppPaymentsRepository.setSubscriber(subscriber)
|
||||
}
|
||||
|
||||
if (accountData.subscriptionManuallyCancelled) {
|
||||
SignalStore.donationsValues().updateLocalStateForManualCancellation(InAppPaymentSubscriberRecord.Type.DONATION)
|
||||
if (accountData.donationSubscriberData.manuallyCancelled) {
|
||||
SignalStore.donationsValues().updateLocalStateForManualCancellation(InAppPaymentSubscriberRecord.Type.DONATION)
|
||||
}
|
||||
}
|
||||
|
||||
if (accountData.avatarUrlPath.isNotEmpty()) {
|
||||
|
||||
Reference in New Issue
Block a user