Add read support for binary service ids.

This commit is contained in:
Michelle Tang
2025-10-28 14:29:43 -04:00
committed by jeffrey-signal
parent bf4aa9cae9
commit f16405fabf
48 changed files with 399 additions and 205 deletions

View File

@@ -620,7 +620,7 @@ class DistributionListTables constructor(context: Context?, databaseHelper: Sign
}
val privacyMode: DistributionListPrivacyMode = when {
insert.proto.isBlockList && insert.proto.recipientServiceIds.isEmpty() -> DistributionListPrivacyMode.ALL
insert.proto.isBlockList && insert.proto.recipientServiceIds.isEmpty() && insert.proto.recipientServiceIdsBinary.isEmpty() -> DistributionListPrivacyMode.ALL
insert.proto.isBlockList -> DistributionListPrivacyMode.ALL_EXCEPT
else -> DistributionListPrivacyMode.ONLY_WITH
}
@@ -666,7 +666,7 @@ class DistributionListTables constructor(context: Context?, databaseHelper: Sign
}
val privacyMode: DistributionListPrivacyMode = when {
update.new.proto.isBlockList && update.new.proto.recipientServiceIds.isEmpty() -> DistributionListPrivacyMode.ALL
update.new.proto.isBlockList && update.new.proto.recipientServiceIds.isEmpty() && update.new.proto.recipientServiceIdsBinary.isEmpty() -> DistributionListPrivacyMode.ALL
update.new.proto.isBlockList -> DistributionListPrivacyMode.ALL_EXCEPT
else -> DistributionListPrivacyMode.ONLY_WITH
}

View File

@@ -4888,7 +4888,7 @@ open class MessageTable(context: Context?, databaseHelper: SignalDatabase) : Dat
writableDatabase.withinTransaction {
for (readMessage in readMessages) {
val authorId: RecipientId = recipients.getOrInsertFromServiceId(ServiceId.parseOrThrow(readMessage.senderAci!!))
val authorId: RecipientId = recipients.getOrInsertFromServiceId(ServiceId.ACI.parseOrThrow(readMessage.senderAci, readMessage.senderAciBinary))
val result: TimestampReadResult = setTimestampReadFromSyncMessageInternal(
messageId = SyncMessageId(authorId, readMessage.timestamp!!),

View File

@@ -869,7 +869,7 @@ open class RecipientTable(context: Context, databaseHelper: SignalDatabase) : Da
val recipientId: RecipientId
if (id < 0) {
Log.w(TAG, "[applyStorageSyncContactInsert] Failed to insert. Possibly merging.")
recipientId = getAndPossiblyMerge(aci = ACI.parseOrNull(insert.proto.aci), pni = PNI.parseOrNull(insert.proto.pni), e164 = insert.proto.e164.nullIfBlank(), pniVerified = insert.proto.pniSignatureVerified)
recipientId = getAndPossiblyMerge(aci = ACI.parseOrNull(insert.proto.aci, insert.proto.aciBinary), pni = PNI.parseOrNull(insert.proto.pni, insert.proto.pniBinary), e164 = insert.proto.e164.nullIfBlank(), pniVerified = insert.proto.pniSignatureVerified)
resolvePotentialUsernameConflicts(values.getAsString(USERNAME), recipientId)
db.update(TABLE_NAME, values, ID_WHERE, SqlUtil.buildArgs(recipientId))
@@ -917,7 +917,7 @@ open class RecipientTable(context: Context, databaseHelper: SignalDatabase) : Da
var recipientId = getByColumn(STORAGE_SERVICE_ID, Base64.encodeWithPadding(update.old.id.raw)).get()
Log.w(TAG, "[applyStorageSyncContactUpdate] Found user $recipientId. Possibly merging.")
recipientId = getAndPossiblyMerge(aci = ACI.parseOrNull(update.new.proto.aci), pni = PNI.parseOrNull(update.new.proto.pni), e164 = update.new.proto.e164.nullIfBlank(), pniVerified = update.new.proto.pniSignatureVerified)
recipientId = getAndPossiblyMerge(aci = ACI.parseOrNull(update.new.proto.aci, update.new.proto.aciBinary), pni = PNI.parseOrNull(update.new.proto.pni, update.new.proto.pniBinary), e164 = update.new.proto.e164.nullIfBlank(), pniVerified = update.new.proto.pniSignatureVerified)
Log.w(TAG, "[applyStorageSyncContactUpdate] Merged into $recipientId")
resolvePotentialUsernameConflicts(values.getAsString(USERNAME), recipientId)
@@ -943,7 +943,7 @@ open class RecipientTable(context: Context, databaseHelper: SignalDatabase) : Da
val oldIdentityRecord = identityStore.getIdentityRecord(recipientId)
if (update.new.proto.identityKey.isNotEmpty() && update.new.proto.signalAci != null) {
val identityKey = IdentityKey(update.new.proto.identityKey.toByteArray(), 0)
identities.updateIdentityAfterSync(update.new.proto.aci, recipientId, identityKey, StorageSyncModels.remoteToLocalIdentityStatus(update.new.proto.identityState))
identities.updateIdentityAfterSync(update.new.proto.signalAci!!.toString(), recipientId, identityKey, StorageSyncModels.remoteToLocalIdentityStatus(update.new.proto.identityState))
}
val newIdentityRecord = identityStore.getIdentityRecord(recipientId)

View File

@@ -8,6 +8,7 @@ import org.whispersystems.signalservice.api.push.DistributionId
import org.whispersystems.signalservice.api.push.ServiceId
import org.whispersystems.signalservice.api.push.SignalServiceAddress
import org.whispersystems.signalservice.internal.push.SyncMessage
import org.whispersystems.signalservice.internal.util.Util
/**
* Represents a list of, or update to a list of, who can access a story through what
@@ -88,9 +89,9 @@ data class SentStorySyncManifest(
}
fun fromRecipientsSet(recipients: List<SyncMessage.Sent.StoryMessageRecipient>): SentStorySyncManifest {
val entries = recipients.toSet().filter { it.destinationServiceId != null }.map { recipient ->
val entries = recipients.toSet().filter { Util.anyNotNull(it.destinationServiceId, it.destinationServiceIdBinary) }.map { recipient ->
Entry(
recipientId = RecipientId.from(ServiceId.parseOrThrow(recipient.destinationServiceId!!)),
recipientId = RecipientId.from(ServiceId.parseOrThrow(recipient.destinationServiceId, recipient.destinationServiceIdBinary)),
allowedToReply = recipient.isAllowedToReply!!,
distributionLists = recipient.distributionListIds.map { DistributionId.from(it) }
)

View File

@@ -1605,7 +1605,7 @@ class ThreadTable(context: Context, databaseHelper: SignalDatabase) : DatabaseTa
for (pinned: AccountRecord.PinnedConversation in record.proto.pinnedConversations) {
val pinnedRecipient: Recipient? = if (pinned.contact != null) {
if (ServiceId.parseOrNull(pinned.contact!!.serviceId) != null) {
if (ServiceId.parseOrNull(pinned.contact!!.serviceId, pinned.contact!!.serviceIdBinary) != null) {
Recipient.externalPush(pinned.contact!!.toSignalServiceAddress())
} else {
Log.w(TAG, "Failed to parse serviceId!")

View File

@@ -174,7 +174,8 @@ public class ApplicationDependencyProvider implements AppDependencies.Provider {
Optional.of(new SecurityEventListener(context)),
SignalExecutors.newCachedBoundedExecutor("signal-messages", ThreadUtil.PRIORITY_IMPORTANT_BACKGROUND_THREAD, 1, 16, 30),
RemoteConfig.maxEnvelopeSizeBytes(),
RemoteConfig::useMessageSendRestFallback);
RemoteConfig::useMessageSendRestFallback,
RemoteConfig.useBinaryId());
}
@Override

View File

@@ -30,6 +30,7 @@ import org.thoughtcrime.securesms.recipients.Recipient;
import org.thoughtcrime.securesms.recipients.RecipientId;
import org.thoughtcrime.securesms.recipients.RecipientUtil;
import org.thoughtcrime.securesms.util.AppForegroundObserver;
import org.thoughtcrime.securesms.util.RemoteConfig;
import org.thoughtcrime.securesms.util.TextSecurePreferences;
import org.whispersystems.signalservice.api.SignalServiceMessageSender;
import org.whispersystems.signalservice.api.crypto.UntrustedIdentityException;
@@ -144,7 +145,7 @@ public class MultiDeviceContactUpdateJob extends BaseJob {
Uri updateUri = null;
try {
DeviceContactsOutputStream out = new DeviceContactsOutputStream(writeDetails.outputStream);
DeviceContactsOutputStream out = new DeviceContactsOutputStream(writeDetails.outputStream, RemoteConfig.useBinaryId());
Recipient recipient = Recipient.resolved(recipientId);
if (recipient.getRegistered() == RecipientTable.RegisteredState.NOT_REGISTERED) {
@@ -209,7 +210,7 @@ public class MultiDeviceContactUpdateJob extends BaseJob {
Uri updateUri = null;
try {
DeviceContactsOutputStream out = new DeviceContactsOutputStream(writeDetails.outputStream);
DeviceContactsOutputStream out = new DeviceContactsOutputStream(writeDetails.outputStream, RemoteConfig.useBinaryId());
List<Recipient> recipients = SignalDatabase.recipients().getRecipientsForMultiDeviceSync();
Map<RecipientId, Integer> inboxPositions = SignalDatabase.threads().getInboxPositions();
Set<RecipientId> archived = SignalDatabase.threads().getArchivedRecipients();

View File

@@ -13,7 +13,7 @@ import org.thoughtcrime.securesms.jobmanager.impl.NetworkConstraint;
import org.thoughtcrime.securesms.keyvalue.SignalStore;
import org.thoughtcrime.securesms.net.NotPushRegisteredException;
import org.thoughtcrime.securesms.recipients.Recipient;
import org.thoughtcrime.securesms.util.TextSecurePreferences;
import org.thoughtcrime.securesms.util.RemoteConfig;
import org.whispersystems.signalservice.api.SignalServiceMessageSender;
import org.whispersystems.signalservice.api.crypto.UntrustedIdentityException;
import org.whispersystems.signalservice.api.messages.SignalServiceAttachment;
@@ -72,7 +72,7 @@ public class MultiDeviceProfileKeyUpdateJob extends BaseJob {
}
ByteArrayOutputStream baos = new ByteArrayOutputStream();
DeviceContactsOutputStream out = new DeviceContactsOutputStream(baos);
DeviceContactsOutputStream out = new DeviceContactsOutputStream(baos, RemoteConfig.useBinaryId());
out.write(new DeviceContact(Optional.ofNullable(SignalStore.account().getAci()),
Optional.ofNullable(SignalStore.account().getE164()),

View File

@@ -22,6 +22,7 @@ import org.whispersystems.signalservice.api.push.ServiceId
import org.whispersystems.signalservice.api.push.exceptions.PushNetworkException
import org.whispersystems.signalservice.internal.push.Content
import org.whispersystems.signalservice.internal.push.Envelope
import org.whispersystems.signalservice.internal.util.Util
import java.io.IOException
import java.util.concurrent.TimeUnit
import org.whispersystems.signalservice.api.crypto.protos.EnvelopeMetadata as EnvelopeMetadataProto
@@ -127,8 +128,11 @@ class PushProcessMessageJob private constructor(
}
}
getQueueName(RecipientId.from(groupId))
} else if (result.content.syncMessage != null && result.content.syncMessage!!.sent != null && result.content.syncMessage!!.sent!!.destinationServiceId != null) {
getQueueName(RecipientId.from(ServiceId.parseOrThrow(result.content.syncMessage!!.sent!!.destinationServiceId!!)))
} else if (result.content.syncMessage != null &&
result.content.syncMessage!!.sent != null &&
Util.anyNotNull(result.content.syncMessage!!.sent!!.destinationServiceId, result.content.syncMessage!!.sent!!.destinationServiceIdBinary)
) {
getQueueName(RecipientId.from(ServiceId.parseOrThrow(result.content.syncMessage!!.sent!!.destinationServiceId, result.content.syncMessage!!.sent!!.destinationServiceIdBinary)))
} else {
getQueueName(RecipientId.from(result.metadata.sourceServiceId))
}

View File

@@ -104,12 +104,14 @@ import org.whispersystems.signalservice.api.payments.Money
import org.whispersystems.signalservice.api.push.ServiceId
import org.whispersystems.signalservice.api.push.ServiceId.ACI
import org.whispersystems.signalservice.api.util.Preconditions
import org.whispersystems.signalservice.api.util.UuidUtil
import org.whispersystems.signalservice.internal.push.BodyRange
import org.whispersystems.signalservice.internal.push.Content
import org.whispersystems.signalservice.internal.push.DataMessage
import org.whispersystems.signalservice.internal.push.Envelope
import org.whispersystems.signalservice.internal.push.GroupContextV2
import org.whispersystems.signalservice.internal.push.Preview
import org.whispersystems.signalservice.internal.util.Util
import java.util.Optional
import java.util.UUID
import kotlin.time.Duration
@@ -145,7 +147,7 @@ object DataMessageProcessor {
groupV2 = message.groupV2!!,
senderRecipient = senderRecipient,
groupSecretParams = groupSecretParams,
serverGuid = envelope.serverGuid
serverGuid = UuidUtil.getStringUUID(envelope.serverGuid, envelope.serverGuidBinary)
)
if (groupProcessResult == MessageContentProcessor.Gv2PreProcessResult.IGNORE) {
@@ -304,7 +306,7 @@ object DataMessageProcessor {
serverTimeMillis = envelope.serverTimestamp!!,
receivedTimeMillis = System.currentTimeMillis(),
isUnidentified = metadata.sealedSender,
serverGuid = envelope.serverGuid,
serverGuid = UuidUtil.getStringUUID(envelope.serverGuid, envelope.serverGuidBinary),
type = MessageType.END_SESSION
)
@@ -362,7 +364,7 @@ object DataMessageProcessor {
receivedTimeMillis = receivedTime,
expiresIn = expiresIn.inWholeMilliseconds,
isUnidentified = metadata.sealedSender,
serverGuid = envelope.serverGuid
serverGuid = UuidUtil.getStringUUID(envelope.serverGuid, envelope.serverGuidBinary)
)
val insertResult: InsertResult? = SignalDatabase.messages.insertMessageInbox(mediaMessage, -1).orNull()
@@ -423,7 +425,7 @@ object DataMessageProcessor {
return null
}
val authorServiceId: ServiceId = ServiceId.parseOrThrow(storyContext.authorAci!!)
val authorServiceId: ServiceId = ACI.parseOrThrow(storyContext.authorAci, storyContext.authorAciBinary)
val sentTimestamp = storyContext.sentTimestamp!!
SignalDatabase.messages.beginTransaction()
@@ -473,7 +475,7 @@ object DataMessageProcessor {
body = emoji,
groupId = groupId,
quote = quoteModel,
serverGuid = envelope.serverGuid
serverGuid = UuidUtil.getStringUUID(envelope.serverGuid, envelope.serverGuidBinary)
)
val insertResult: InsertResult? = SignalDatabase.messages.insertMessageInbox(mediaMessage, -1).orNull()
@@ -517,7 +519,7 @@ object DataMessageProcessor {
val emoji: String? = reaction.emoji
val isRemove: Boolean = reaction.remove ?: false
val targetAuthorServiceId: ServiceId = ServiceId.parseOrThrow(reaction.targetAuthorAci!!)
val targetAuthorServiceId: ServiceId = ACI.parseOrThrow(reaction.targetAuthorAci, reaction.targetAuthorAciBinary)
val targetSentTimestamp: Long = reaction.targetSentTimestamp!!
if (targetAuthorServiceId.isUnknown) {
@@ -635,7 +637,7 @@ object DataMessageProcessor {
receivedTimeMillis = receivedTime,
expiresIn = message.expireTimerDuration.inWholeMilliseconds,
isUnidentified = metadata.sealedSender,
serverGuid = envelope.serverGuid,
serverGuid = UuidUtil.getStringUUID(envelope.serverGuid, envelope.serverGuidBinary),
type = if (isActivatePaymentsRequest) MessageType.ACTIVATE_PAYMENTS_REQUEST else MessageType.PAYMENTS_ACTIVATED
)
@@ -686,7 +688,7 @@ object DataMessageProcessor {
receivedTimeMillis = receivedTime,
expiresIn = message.expireTimerDuration.inWholeMilliseconds,
isUnidentified = metadata.sealedSender,
serverGuid = envelope.serverGuid,
serverGuid = UuidUtil.getStringUUID(envelope.serverGuid, envelope.serverGuidBinary),
type = MessageType.PAYMENTS_NOTIFICATION
)
@@ -726,7 +728,7 @@ object DataMessageProcessor {
log(envelope.timestamp!!, "Story reply.")
val storyContext: DataMessage.StoryContext = message.storyContext!!
val authorServiceId: ServiceId = ServiceId.parseOrThrow(storyContext.authorAci!!)
val authorServiceId: ServiceId = ACI.parseOrThrow(storyContext.authorAci, storyContext.authorAciBinary)
val sentTimestamp: Long = if (storyContext.sentTimestamp != null) {
storyContext.sentTimestamp!!
} else {
@@ -786,7 +788,7 @@ object DataMessageProcessor {
return null
}
val bodyRanges: BodyRangeList? = message.bodyRanges.filter { it.mentionAci == null }.toList().toBodyRangeList()
val bodyRanges: BodyRangeList? = message.bodyRanges.filter { Util.allAreNull(it.mentionAci, it.mentionAciBinary) }.toList().toBodyRangeList()
val mediaMessage = IncomingMessage(
type = MessageType.NORMAL,
@@ -801,7 +803,7 @@ object DataMessageProcessor {
groupId = groupId,
quote = quoteModel,
mentions = getMentions(message.bodyRanges),
serverGuid = envelope.serverGuid,
serverGuid = UuidUtil.getStringUUID(envelope.serverGuid, envelope.serverGuidBinary),
messageRanges = bodyRanges
)
@@ -866,7 +868,7 @@ object DataMessageProcessor {
expiresIn = message.expireTimerDuration.inWholeMilliseconds,
isUnidentified = metadata.sealedSender,
body = Base64.encodeWithPadding(dbGiftBadge.encode()),
serverGuid = envelope.serverGuid,
serverGuid = UuidUtil.getStringUUID(envelope.serverGuid, envelope.serverGuidBinary),
giftBadge = dbGiftBadge
)
@@ -910,7 +912,7 @@ object DataMessageProcessor {
val mentions: List<Mention> = getMentions(message.bodyRanges.take(BODY_RANGE_PROCESSING_LIMIT))
val sticker: Attachment? = getStickerAttachment(envelope.timestamp!!, message)
val attachments: List<Attachment> = message.attachments.toPointersWithinLimit()
val messageRanges: BodyRangeList? = if (message.bodyRanges.isNotEmpty()) message.bodyRanges.asSequence().take(BODY_RANGE_PROCESSING_LIMIT).filter { it.mentionAci == null }.toList().toBodyRangeList() else null
val messageRanges: BodyRangeList? = if (message.bodyRanges.isNotEmpty()) message.bodyRanges.asSequence().take(BODY_RANGE_PROCESSING_LIMIT).filter { Util.allAreNull(it.mentionAci, it.mentionAciBinary) }.toList().toBodyRangeList() else null
handlePossibleExpirationUpdate(envelope, metadata, senderRecipient, threadRecipient, groupId, message.expireTimerDuration, message.expireTimerVersion, receivedTime)
@@ -930,7 +932,7 @@ object DataMessageProcessor {
sharedContacts = contacts,
linkPreviews = linkPreviews,
mentions = mentions,
serverGuid = envelope.serverGuid,
serverGuid = UuidUtil.getStringUUID(envelope.serverGuid, envelope.serverGuidBinary),
messageRanges = messageRanges
)
@@ -1006,7 +1008,7 @@ object DataMessageProcessor {
groupId = groupId,
expiresIn = message.expireTimerDuration.inWholeMilliseconds,
isUnidentified = metadata.sealedSender,
serverGuid = envelope.serverGuid
serverGuid = UuidUtil.getStringUUID(envelope.serverGuid, envelope.serverGuidBinary)
)
val insertResult: InsertResult? = SignalDatabase.messages.insertMessageInbox(textMessage).orNull()
@@ -1086,7 +1088,7 @@ object DataMessageProcessor {
groupId = groupId,
expiresIn = message.expireTimerDuration.inWholeMilliseconds,
isUnidentified = metadata.sealedSender,
serverGuid = envelope.serverGuid,
serverGuid = UuidUtil.getStringUUID(envelope.serverGuid, envelope.serverGuidBinary),
poll = Poll(
question = poll.question!!,
allowMultipleVotes = poll.allowMultiple!!,
@@ -1148,7 +1150,7 @@ object DataMessageProcessor {
groupId = groupId,
expiresIn = message.expireTimerDuration.inWholeMilliseconds,
isUnidentified = metadata.sealedSender,
serverGuid = envelope.serverGuid,
serverGuid = UuidUtil.getStringUUID(envelope.serverGuid, envelope.serverGuidBinary),
messageExtras = MessageExtras(pollTerminate = PollTerminate(poll.question, poll.messageId, targetSentTimestamp))
)
@@ -1244,9 +1246,9 @@ object DataMessageProcessor {
fun getMentions(mentionBodyRanges: List<BodyRange>): List<Mention> {
return mentionBodyRanges
.filter { it.mentionAci != null && it.start != null && it.length != null }
.filter { Util.anyNotNull(it.mentionAci, it.mentionAciBinary) && it.start != null && it.length != null }
.mapNotNull {
val aci = ACI.parseOrNull(it.mentionAci)
val aci = ACI.parseOrNull(it.mentionAci, it.mentionAciBinary)
if (aci != null && !aci.isUnknown) {
val id = Recipient.externalPush(aci).id
@@ -1279,7 +1281,7 @@ object DataMessageProcessor {
return null
}
val authorId = Recipient.externalPush(ServiceId.parseOrThrow(quote.authorAci!!)).id
val authorId = Recipient.externalPush(ACI.parseOrThrow(quote.authorAci, quote.authorAciBinary)).id
var quotedMessage = SignalDatabase.messages.getMessageFor(quote.id!!, authorId) as? MmsMessageRecord
if (quotedMessage != null && isSenderValid(quotedMessage, timestamp, senderRecipient, threadRecipient) && !quotedMessage.isRemoteDelete) {

View File

@@ -31,9 +31,11 @@ import org.thoughtcrime.securesms.util.MessageConstraintsUtil
import org.thoughtcrime.securesms.util.hasAudio
import org.thoughtcrime.securesms.util.hasSharedContact
import org.whispersystems.signalservice.api.crypto.EnvelopeMetadata
import org.whispersystems.signalservice.api.util.UuidUtil
import org.whispersystems.signalservice.internal.push.Content
import org.whispersystems.signalservice.internal.push.DataMessage
import org.whispersystems.signalservice.internal.push.Envelope
import org.whispersystems.signalservice.internal.util.Util
object EditMessageProcessor {
fun process(
@@ -120,7 +122,7 @@ object EditMessageProcessor {
message: DataMessage,
targetMessage: MmsMessageRecord
): InsertResult? {
val messageRanges: BodyRangeList? = message.bodyRanges.filter { it.mentionAci == null }.toList().toBodyRangeList()
val messageRanges: BodyRangeList? = message.bodyRanges.filter { Util.allAreNull(it.mentionAci, it.mentionAciBinary) }.toList().toBodyRangeList()
val targetQuote = targetMessage.quote
val quote: QuoteModel? = if (targetQuote != null && (message.quote != null || (targetMessage.parentStoryId != null && message.storyContext != null))) {
QuoteModel(
@@ -156,7 +158,7 @@ object EditMessageProcessor {
sharedContacts = emptyList(),
linkPreviews = DataMessageProcessor.getLinkPreviews(message.preview, message.body ?: "", false),
mentions = DataMessageProcessor.getMentions(message.bodyRanges),
serverGuid = envelope.serverGuid,
serverGuid = UuidUtil.getStringUUID(envelope.serverGuid, envelope.serverGuidBinary),
messageRanges = messageRanges
)
@@ -191,7 +193,7 @@ object EditMessageProcessor {
parentStoryId = targetMessage.parentStoryId,
expiresIn = targetMessage.expiresIn,
isUnidentified = metadata.sealedSender,
serverGuid = envelope.serverGuid
serverGuid = UuidUtil.getStringUUID(envelope.serverGuid, envelope.serverGuidBinary)
)
return SignalDatabase.messages.insertEditMessageInbox(textMessage, targetMessage).orNull()

View File

@@ -334,7 +334,7 @@ class IncomingMessageObserver(
}
private fun processReceipt(envelope: Envelope) {
val serviceId = ServiceId.parseOrNull(envelope.sourceServiceId)
val serviceId = ServiceId.parseOrNull(envelope.sourceServiceId, envelope.sourceServiceIdBinary)
if (serviceId == null) {
Log.w(TAG, "Invalid envelope sourceServiceId!")
return

View File

@@ -659,7 +659,7 @@ open class MessageContentProcessor(private val context: Context) {
private fun handleIndividualRetryReceipt(requester: Recipient, messageLogEntry: MessageLogEntry?, envelope: Envelope, metadata: EnvelopeMetadata, decryptionErrorMessage: DecryptionErrorMessage) {
var archivedSession = false
if (ServiceId.parseOrNull(envelope.destinationServiceId) is ServiceId.PNI) {
if (ServiceId.parseOrNull(envelope.destinationServiceId, envelope.destinationServiceIdBinary) is ServiceId.PNI) {
warn(envelope.timestamp!!, "[RetryReceipt-I] Destination is our PNI. Ignoring.")
return
}

View File

@@ -67,9 +67,11 @@ import org.whispersystems.signalservice.api.push.ServiceId
import org.whispersystems.signalservice.api.push.ServiceId.ACI
import org.whispersystems.signalservice.api.push.ServiceId.PNI
import org.whispersystems.signalservice.api.push.SignalServiceAddress
import org.whispersystems.signalservice.api.util.UuidUtil
import org.whispersystems.signalservice.internal.push.Content
import org.whispersystems.signalservice.internal.push.Envelope
import org.whispersystems.signalservice.internal.push.PniSignatureMessage
import org.whispersystems.signalservice.internal.util.Util
import java.util.Optional
import kotlin.time.Duration.Companion.nanoseconds
import kotlin.time.DurationUnit
@@ -100,7 +102,7 @@ object MessageDecryptor {
val selfAci: ACI = SignalStore.account.requireAci()
val selfPni: PNI = SignalStore.account.requirePni()
val destination: ServiceId? = ServiceId.parseOrNull(envelope.destinationServiceId)
val destination: ServiceId? = ServiceId.parseOrNull(envelope.destinationServiceId, envelope.destinationServiceIdBinary)
if (destination == null) {
Log.w(TAG, "${logPrefix(envelope)} Missing destination address! Invalid message, ignoring.")
@@ -112,10 +114,10 @@ object MessageDecryptor {
return Result.Ignore(envelope, serverDeliveredTimestamp, emptyList())
}
if (destination == selfPni && envelope.sourceServiceId != null) {
if (destination == selfPni && Util.anyNotNull(envelope.sourceServiceId, envelope.sourceServiceIdBinary)) {
Log.i(TAG, "${logPrefix(envelope)} Received a message at our PNI. Marking as needing a PNI signature.")
val sourceServiceId = ServiceId.parseOrNull(envelope.sourceServiceId)
val sourceServiceId = ServiceId.parseOrNull(envelope.sourceServiceId, envelope.sourceServiceIdBinary)
if (sourceServiceId != null) {
val sender = RecipientId.from(sourceServiceId)
@@ -125,7 +127,7 @@ object MessageDecryptor {
}
}
if (destination == selfPni && envelope.sourceServiceId == null) {
if (destination == selfPni && Util.allAreNull(envelope.sourceServiceId, envelope.sourceServiceIdBinary)) {
Log.w(TAG, "${logPrefix(envelope)} Got a sealed sender message to our PNI? Invalid message, ignoring.")
return Result.Ignore(envelope, serverDeliveredTimestamp, emptyList())
}
@@ -164,7 +166,7 @@ object MessageDecryptor {
return Result.Ignore(envelope, serverDeliveredTimestamp, followUpOperations.toUnmodifiableList())
}
Log.d(TAG, "${logPrefix(envelope, cipherResult)} Successfully decrypted the envelope in ${(endTimeNanos - startTimeNanos).nanoseconds.toDouble(DurationUnit.MILLISECONDS).roundedString(2)} ms (GUID ${envelope.serverGuid}). Delivery latency: ${serverDeliveredTimestamp - envelope.serverTimestamp!!} ms, Urgent: ${envelope.urgent}")
Log.d(TAG, "${logPrefix(envelope, cipherResult)} Successfully decrypted the envelope in ${(endTimeNanos - startTimeNanos).nanoseconds.toDouble(DurationUnit.MILLISECONDS).roundedString(2)} ms (GUID ${UuidUtil.getStringUUID(envelope.serverGuid, envelope.serverGuidBinary)}). Delivery latency: ${serverDeliveredTimestamp - envelope.serverTimestamp!!} ms, Urgent: ${envelope.urgent}")
val validationResult: EnvelopeContentValidator.Result = EnvelopeContentValidator.validate(envelope, cipherResult.content, SignalStore.account.aci!!)
@@ -289,7 +291,7 @@ object MessageDecryptor {
followUpOperations: MutableList<FollowUpOperation>,
protocolException: ProtocolException
): Result {
if (ServiceId.parseOrNull(envelope.destinationServiceId) == SignalStore.account.pni) {
if (ServiceId.parseOrNull(envelope.destinationServiceId, envelope.destinationServiceIdBinary) == SignalStore.account.pni) {
Log.w(TAG, "${logPrefix(envelope)} Decryption error for message sent to our PNI! Ignoring.")
return Result.Ignore(envelope, serverDeliveredTimestamp, followUpOperations)
}
@@ -475,7 +477,7 @@ object MessageDecryptor {
}
private fun logPrefix(envelope: Envelope): String {
return logPrefix(envelope.timestamp!!, ServiceId.parseOrNull(envelope.sourceServiceId)?.logString() ?: "<sealed>", envelope.sourceDevice)
return logPrefix(envelope.timestamp!!, ServiceId.parseOrNull(envelope.sourceServiceId, envelope.sourceServiceIdBinary)?.logString() ?: "<sealed>", envelope.sourceDevice)
}
private fun logPrefix(envelope: Envelope, sender: ServiceId?): String {
@@ -494,7 +496,7 @@ object MessageDecryptor {
return if (exception.sender != null) {
logPrefix(envelope.timestamp!!, ServiceId.parseOrNull(exception.sender)?.logString() ?: "?", exception.senderDevice)
} else {
logPrefix(envelope.timestamp!!, envelope.sourceServiceId, envelope.sourceDevice)
logPrefix(envelope.timestamp!!, ServiceId.parseOrNull(envelope.sourceServiceId, envelope.sourceServiceIdBinary).toString(), envelope.sourceDevice)
}
}

View File

@@ -145,14 +145,14 @@ object SignalServiceProtoUtil {
}
fun Sent.isUnidentified(serviceId: ServiceId?): Boolean {
return serviceId != null && unidentifiedStatus.firstOrNull { ServiceId.parseOrNull(it.destinationServiceId) == serviceId }?.unidentified ?: false
return serviceId != null && unidentifiedStatus.firstOrNull { ServiceId.parseOrNull(it.destinationServiceId, it.destinationServiceIdBinary) == serviceId }?.unidentified ?: false
}
val Sent.serviceIdsToUnidentifiedStatus: Map<ServiceId, Boolean>
get() {
return unidentifiedStatus
.mapNotNull { status ->
val serviceId = ServiceId.parseOrNull(status.destinationServiceId)
val serviceId = ServiceId.parseOrNull(status.destinationServiceId, status.destinationServiceIdBinary)
if (serviceId != null) {
serviceId to (status.unidentified ?: false)
} else {

View File

@@ -21,10 +21,12 @@ import org.thoughtcrime.securesms.recipients.Recipient
import org.thoughtcrime.securesms.stories.Stories
import org.thoughtcrime.securesms.util.RemoteConfig
import org.whispersystems.signalservice.api.crypto.EnvelopeMetadata
import org.whispersystems.signalservice.api.util.UuidUtil
import org.whispersystems.signalservice.internal.push.Content
import org.whispersystems.signalservice.internal.push.Envelope
import org.whispersystems.signalservice.internal.push.StoryMessage
import org.whispersystems.signalservice.internal.push.TextAttachment
import org.whispersystems.signalservice.internal.util.Util
object StoryMessageProcessor {
@@ -75,8 +77,8 @@ object StoryMessageProcessor {
body = "",
isStoryEmbed = true
),
serverGuid = envelope.serverGuid,
messageRanges = storyMessage.bodyRanges.filter { it.mentionAci == null }.toBodyRangeList()
serverGuid = UuidUtil.getStringUUID(envelope.serverGuid, envelope.serverGuidBinary),
messageRanges = storyMessage.bodyRanges.filter { Util.allAreNull(it.mentionAci, it.mentionAciBinary) }.toBodyRangeList()
)
insertResult = SignalDatabase.messages.insertMessageInbox(mediaMessage, -1).orNull()

View File

@@ -143,6 +143,7 @@ import java.util.concurrent.TimeUnit
import kotlin.time.Duration
import kotlin.time.Duration.Companion.days
import kotlin.time.Duration.Companion.seconds
import org.whispersystems.signalservice.internal.util.Util as Utils
object SyncMessageProcessor {
@@ -287,7 +288,7 @@ object SyncMessageProcessor {
continue
}
val pni = PNI.parsePrefixedOrNull(status.destinationServiceId)
val pni = PNI.parsePrefixedOrNull(status.destinationServiceId, status.destinationServiceIdBinary)
if (pni == null) {
continue
}
@@ -313,7 +314,7 @@ object SyncMessageProcessor {
return if (message.message.hasGroupContext) {
Recipient.externalPossiblyMigratedGroup(GroupId.v2(message.message!!.groupV2!!.groupMasterKey))
} else {
Recipient.externalPush(SignalServiceAddress(ServiceId.parseOrThrow(message.destinationServiceId!!), message.destinationE164))
Recipient.externalPush(SignalServiceAddress(ServiceId.parseOrThrow(message.destinationServiceId, message.destinationServiceIdBinary), message.destinationE164))
}
}
@@ -341,7 +342,7 @@ object SyncMessageProcessor {
val toRecipient: Recipient = if (message.hasGroupContext) {
Recipient.externalPossiblyMigratedGroup(GroupId.v2(message.groupV2!!.groupMasterKey))
} else {
Recipient.externalPush(ServiceId.parseOrThrow(sent.destinationServiceId!!))
Recipient.externalPush(ServiceId.parseOrThrow(sent.destinationServiceId, sent.destinationServiceIdBinary))
}
if (message.isMediaMessage) {
@@ -364,7 +365,7 @@ object SyncMessageProcessor {
log(envelopeTimestamp, "Synchronize sent edit text message for message: ${targetMessage.id}")
val body = message.body ?: ""
val bodyRanges = message.bodyRanges.filter { it.mentionAci == null }.toBodyRangeList()
val bodyRanges = message.bodyRanges.filter { Utils.allAreNull(it.mentionAci, it.mentionAciBinary) }.toBodyRangeList()
val threadId = SignalDatabase.threads.getOrCreateThreadIdFor(toRecipient)
val isGroup = toRecipient.isGroup
@@ -740,7 +741,7 @@ object SyncMessageProcessor {
val reaction: DataMessage.Reaction? = dataMessage.reaction
val parentStoryId: ParentStoryId
val authorServiceId: ServiceId = ServiceId.parseOrThrow(storyContext.authorAci!!)
val authorServiceId: ServiceId = ACI.parseOrThrow(storyContext.authorAci, storyContext.authorAciBinary)
val sentTimestamp: Long = storyContext.sentTimestamp!!
val recipient: Recipient = getSyncMessageDestination(sent)
var quoteModel: QuoteModel? = null
@@ -903,7 +904,7 @@ object SyncMessageProcessor {
val dataMessage: DataMessage = sent.message!!
val body = dataMessage.body ?: ""
val expiresInMillis = dataMessage.expireTimerDuration.inWholeMilliseconds
val bodyRanges = dataMessage.bodyRanges.filter { it.mentionAci == null }.toBodyRangeList()
val bodyRanges = dataMessage.bodyRanges.filter { Utils.allAreNull(it.mentionAci, it.mentionAciBinary) }.toBodyRangeList()
if (recipient.expiresInSeconds != dataMessage.expireTimerDuration.inWholeSeconds.toInt() || ((dataMessage.expireTimerVersion ?: -1) > recipient.expireTimerVersion)) {
handleSynchronizeSentExpirationUpdate(sent, sideEffect = true)
@@ -1017,7 +1018,7 @@ object SyncMessageProcessor {
val records = viewedMessages
.mapNotNull { message ->
val author = Recipient.externalPush(ServiceId.parseOrThrow(message.senderAci!!)).id
val author = Recipient.externalPush(ACI.parseOrThrow(message.senderAci, message.senderAciBinary)).id
if (message.timestamp != null) {
SignalDatabase.messages.getMessageFor(message.timestamp!!, author)
} else {
@@ -1049,7 +1050,7 @@ object SyncMessageProcessor {
private fun handleSynchronizeViewOnceOpenMessage(context: Context, openMessage: ViewOnceOpen, envelopeTimestamp: Long, earlyMessageCacheEntry: EarlyMessageCacheEntry?) {
log(envelopeTimestamp, "Handling a view-once open for message: " + openMessage.timestamp)
val author: RecipientId = Recipient.externalPush(ServiceId.parseOrThrow(openMessage.senderAci!!)).id
val author: RecipientId = Recipient.externalPush(ACI.parseOrThrow(openMessage.senderAci, openMessage.senderAciBinary)).id
val timestamp: Long = if (openMessage.timestamp != null) {
openMessage.timestamp!!
} else {
@@ -1122,7 +1123,7 @@ object SyncMessageProcessor {
}
private fun handleSynchronizeBlockedListMessage(blockMessage: Blocked, envelopeTimestamp: Long) {
val blockedAcis = blockMessage.acis.mapNotNull { ACI.parseOrNull(it) }
val blockedAcis = if (blockMessage.acisBinary.isNotEmpty()) { blockMessage.acisBinary.mapNotNull { ACI.parseOrNull(it) } } else blockMessage.acis.mapNotNull { ACI.parseOrNull(it) }
val blockedE164s = blockMessage.numbers
val blockedGroupIds = blockMessage.groupIds.map { it.toByteArray() }
log(envelopeTimestamp, "Synchronize block message. Counts: (ACI: ${blockedAcis.size}, E164: ${blockedE164s.size}, Group: ${blockedGroupIds.size})")
@@ -1144,8 +1145,8 @@ object SyncMessageProcessor {
private fun handleSynchronizeMessageRequestResponse(response: MessageRequestResponse, envelopeTimestamp: Long) {
log(envelopeTimestamp, "Synchronize message request response.")
val recipient: Recipient = if (response.threadAci != null) {
Recipient.externalPush(ServiceId.parseOrThrow(response.threadAci!!))
val recipient: Recipient = if (Utils.anyNotNull(response.threadAci, response.threadAciBinary)) {
Recipient.externalPush(ACI.parseOrThrow(response.threadAci, response.threadAciBinary))
} else if (response.groupId != null) {
val groupId: GroupId = GroupId.push(response.groupId!!)
Recipient.externalPossiblyMigratedGroup(groupId)
@@ -1858,6 +1859,7 @@ object SyncMessageProcessor {
}
private fun ConversationIdentifier.toRecipientId(): RecipientId? {
val threadServiceId = ServiceId.parseOrNull(this.threadServiceId, this.threadServiceIdBinary)
return when {
threadGroupId != null -> {
try {
@@ -1869,9 +1871,7 @@ object SyncMessageProcessor {
}
threadServiceId != null -> {
ServiceId.parseOrNull(threadServiceId)?.let {
SignalDatabase.recipients.getOrInsertFromServiceId(it)
}
SignalDatabase.recipients.getOrInsertFromServiceId(threadServiceId)
}
threadE164 != null -> {
@@ -1885,8 +1885,8 @@ object SyncMessageProcessor {
}
private fun AddressableMessage.toSyncMessageId(envelopeTimestamp: Long): MessageTable.SyncMessageId? {
return if (this.sentTimestamp != null && (this.authorServiceId != null || this.authorE164 != null)) {
val serviceId = ServiceId.parseOrNull(this.authorServiceId)
return if (this.sentTimestamp != null && Utils.anyNotNull(this.authorServiceId, this.authorServiceIdBinary) || this.authorE164 != null) {
val serviceId = ServiceId.parseOrNull(this.authorServiceId, this.authorServiceIdBinary)
val id = if (serviceId != null) {
SignalDatabase.recipients.getOrInsertFromServiceId(serviceId)
} else {

View File

@@ -99,7 +99,7 @@ class ChatFolderRecordProcessor : DefaultStorageRecordProcessor<SignalChatFolder
private fun containsInvalidServiceId(recipients: List<Recipient>): Boolean {
return recipients.any { recipient ->
recipient.contact != null && ServiceId.parseOrNull(recipient.contact!!.serviceId) == null
recipient.contact != null && ServiceId.parseOrNull(recipient.contact!!.serviceId, recipient.contact!!.serviceIdBinary) == null
}
}
}

View File

@@ -235,6 +235,8 @@ class ContactRecordProcessor(
pniSignatureVerified = remote.proto.pniSignatureVerified || local.proto.pniSignatureVerified
note = remote.proto.note.nullIfBlank() ?: ""
avatarColor = if (SignalStore.account.isPrimaryDevice) local.proto.avatarColor else remote.proto.avatarColor
aciBinary = local.proto.aciBinary.nullIfEmpty() ?: remote.proto.aciBinary
pniBinary = mergedPni?.toByteStringWithoutPrefix() ?: byteArrayOf().toByteString()
}.build().toSignalContactRecord(StorageId.forContact(keyGenerator.generate()))
val matchesRemote = doParamsMatch(remote, merged)
@@ -265,9 +267,9 @@ class ContactRecordProcessor(
override fun compare(lhs: SignalContactRecord, rhs: SignalContactRecord): Int {
return if (
(lhs.proto.signalAci != null && lhs.proto.aci == rhs.proto.aci) ||
(lhs.proto.signalAci != null && lhs.proto.aci == rhs.proto.aci && lhs.proto.aciBinary == rhs.proto.aciBinary) ||
(lhs.proto.e164.isNotBlank() && lhs.proto.e164 == rhs.proto.e164) ||
(lhs.proto.signalPni != null && lhs.proto.pni == rhs.proto.pni)
(lhs.proto.signalPni != null && lhs.proto.pni == rhs.proto.pni && lhs.proto.pniBinary == rhs.proto.pniBinary)
) {
0
} else {

View File

@@ -89,7 +89,7 @@ class NotificationProfileRecordProcessor : DefaultStorageRecordProcessor<SignalN
private fun containsInvalidServiceId(recipients: List<Recipient>): Boolean {
return recipients.any { recipient ->
recipient.contact != null && ServiceId.parseOrNull(recipient.contact!!.serviceId) == null
recipient.contact != null && ServiceId.parseOrNull(recipient.contact!!.serviceId, recipient.contact!!.serviceIdBinary) == null
}
}
}

View File

@@ -28,6 +28,7 @@ import org.thoughtcrime.securesms.keyvalue.PhoneNumberPrivacyValues
import org.thoughtcrime.securesms.notifications.profiles.NotificationProfile
import org.thoughtcrime.securesms.recipients.Recipient
import org.thoughtcrime.securesms.recipients.RecipientId
import org.thoughtcrime.securesms.util.RemoteConfig
import org.whispersystems.signalservice.api.push.ServiceId
import org.whispersystems.signalservice.api.push.SignalServiceAddress
import org.whispersystems.signalservice.api.storage.IAPSubscriptionId
@@ -133,7 +134,8 @@ object StorageSyncModels {
AccountRecord.PinnedConversation(
contact = AccountRecord.PinnedConversation.Contact(
serviceId = settings.serviceId?.toString() ?: "",
e164 = settings.e164 ?: ""
e164 = settings.e164 ?: "",
serviceIdBinary = settings.serviceId?.toByteString().takeIf { RemoteConfig.useBinaryId } ?: ByteString.EMPTY
)
)
}
@@ -210,6 +212,8 @@ object StorageSyncModels {
nickname = recipient.nickname.takeUnless { it.isEmpty }?.let { ContactRecord.Name(given = it.givenName, family = it.familyName) }
note = recipient.note ?: ""
avatarColor = localToRemoteAvatarColor(recipient.avatarColor)
aciBinary = recipient.aci?.toByteString()?.takeIf { RemoteConfig.useBinaryId } ?: ByteString.EMPTY
pniBinary = recipient.pni?.toByteStringWithoutPrefix()?.takeIf { RemoteConfig.useBinaryId } ?: ByteString.EMPTY
}.build().toSignalContactRecord(StorageId.forContact(rawStorageId))
}
@@ -294,6 +298,14 @@ object StorageSyncModels {
.map { Recipient.resolved(it) }
.filter { it.hasServiceId }
.map { it.requireServiceId().toString() }
recipientServiceIdsBinary = if (RemoteConfig.useBinaryId) {
record.getMembersToSync()
.map { Recipient.resolved(it) }
.filter { it.hasServiceId }
.map { it.requireServiceId().toByteString() }
} else {
emptyList()
}
allowsReplies = record.allowsReplies
isBlockList = record.privacyMode.isBlockList
}.build().toSignalStoryDistributionListRecord(StorageId.forStoryDistributionList(rawStorageId))
@@ -493,7 +505,13 @@ object StorageSyncModels {
} else {
when (recipient.recipientType) {
RecipientType.INDIVIDUAL -> {
RemoteRecipient(contact = RemoteRecipient.Contact(serviceId = recipient.serviceId?.toString() ?: "", e164 = recipient.e164 ?: ""))
RemoteRecipient(
contact = RemoteRecipient.Contact(
serviceId = recipient.serviceId?.toString() ?: "",
e164 = recipient.e164 ?: "",
serviceIdBinary = recipient.serviceId?.toByteString().takeIf { RemoteConfig.useBinaryId } ?: ByteString.EMPTY
)
)
}
RecipientType.GV1 -> {
RemoteRecipient(legacyGroupId = recipient.groupId!!.requireV1().decodedId.toByteString())
@@ -509,7 +527,7 @@ object StorageSyncModels {
fun remoteToLocalRecipient(remoteRecipient: RemoteRecipient): Recipient? {
return if (remoteRecipient.contact != null) {
val serviceId = ServiceId.parseOrNull(remoteRecipient.contact!!.serviceId)
val serviceId = ServiceId.parseOrNull(remoteRecipient.contact!!.serviceId, remoteRecipient.contact!!.serviceIdBinary)
val e164 = remoteRecipient.contact!!.e164
Recipient.externalPush(SignalServiceAddress(serviceId, e164))
} else if (remoteRecipient.legacyGroupId != null) {

View File

@@ -14,6 +14,7 @@ import org.whispersystems.signalservice.api.storage.SignalContactRecord;
import org.whispersystems.signalservice.api.storage.SignalStorageManifest;
import org.whispersystems.signalservice.api.storage.SignalStorageRecord;
import org.whispersystems.signalservice.api.storage.StorageId;
import org.whispersystems.signalservice.api.util.UuidUtil;
import org.whispersystems.signalservice.internal.storage.protos.ContactRecord;
import org.whispersystems.signalservice.internal.storage.protos.ManifestRecord;
@@ -181,8 +182,8 @@ public final class StorageSyncValidations {
if (insert.getProto().contact != null) {
ContactRecord contact = insert.getProto().contact;
if (self.requireAci().equals(ServiceId.ACI.parseOrNull(contact.aci)) ||
(self.getPni().isPresent() && self.requirePni().equals(ServiceId.PNI.parseOrNull(contact.pni))) ||
if (self.requireAci().equals(ServiceId.ACI.parseOrNull(contact.aci, contact.aciBinary)) ||
(self.getPni().isPresent() && self.requirePni().equals(ServiceId.PNI.parseOrNull(contact.pni, contact.pniBinary))) ||
(self.getE164().isPresent() && self.requireE164().equals(contact.e164)))
{
throw new SelfAddedAsContactError();

View File

@@ -99,6 +99,7 @@ class StoryDistributionListRecordProcessor : DefaultStorageRecordProcessor<Signa
deletedAtTimestamp = remote.proto.deletedAtTimestamp
allowsReplies = remote.proto.allowsReplies
isBlockList = remote.proto.isBlockList
recipientServiceIdsBinary = remote.proto.recipientServiceIdsBinary
}.build().toSignalStoryDistributionListRecord(StorageId.forStoryDistributionList(keyGenerator.generate()))
val matchesRemote = doParamsMatch(remote, merged)

View File

@@ -38,6 +38,7 @@ import org.whispersystems.signalservice.api.SignalSessionLock;
import org.whispersystems.signalservice.api.messages.multidevice.VerifiedMessage;
import org.whispersystems.signalservice.api.push.ServiceId;
import org.whispersystems.signalservice.api.push.SignalServiceAddress;
import org.whispersystems.signalservice.api.util.UuidUtil;
import org.whispersystems.signalservice.internal.push.Verified;
import java.util.List;
@@ -185,7 +186,7 @@ public final class IdentityUtil {
}
public static void processVerifiedMessage(Context context, Verified verified) throws InvalidKeyException {
SignalServiceAddress destination = new SignalServiceAddress(ServiceId.parseOrThrow(verified.destinationAci));
SignalServiceAddress destination = new SignalServiceAddress(ServiceId.ACI.parseOrThrow(verified.destinationAci, verified.destinationAciBinary));
IdentityKey identityKey = new IdentityKey(verified.identityKey.toByteArray(), 0);
VerifiedMessage.VerifiedState state;

View File

@@ -1181,6 +1181,15 @@ object RemoteConfig {
hotSwappable = true
)
/** Whether or not to send over binary service ids (alongside string service ids). */
@JvmStatic
@get:JvmName("useBinaryId")
val useBinaryId: Boolean by remoteBoolean(
key = "android.useBinaryServiceId",
defaultValue = false,
hotSwappable = false
)
@JvmStatic
@get:JvmName("receivePolls")
val receivePolls: Boolean by remoteBoolean(