diff --git a/app/build.gradle.kts b/app/build.gradle.kts index 6b7b602007..c7a2d1cc87 100644 --- a/app/build.gradle.kts +++ b/app/build.gradle.kts @@ -238,6 +238,7 @@ android { buildConfigField("String", "STRIPE_PUBLISHABLE_KEY", "\"pk_live_6cmGZopuTsV8novGgJJW9JpC00vLIgtQ1D\"") buildConfigField("boolean", "TRACING_ENABLED", "false") buildConfigField("boolean", "LINK_DEVICE_UX_ENABLED", "false") + buildConfigField("boolean", "USE_STRING_ID", "true") ndk { abiFilters += listOf("armeabi-v7a", "arm64-v8a", "x86", "x86_64") @@ -412,6 +413,7 @@ android { buildConfigField("String", "RECAPTCHA_PROOF_URL", "\"https://signalcaptchas.org/staging/challenge/generate.html\"") buildConfigField("org.signal.libsignal.net.Network.Environment", "LIBSIGNAL_NET_ENV", "org.signal.libsignal.net.Network.Environment.STAGING") buildConfigField("int", "LIBSIGNAL_LOG_LEVEL", "org.signal.libsignal.protocol.logging.SignalProtocolLogger.DEBUG") + buildConfigField("boolean", "USE_STRING_ID", "false") buildConfigField("String", "BUILD_ENVIRONMENT_TYPE", "\"Staging\"") buildConfigField("String", "STRIPE_PUBLISHABLE_KEY", "\"pk_test_sngOd8FnXNkpce9nPXawKrJD00kIDngZkD\"") diff --git a/app/src/main/java/org/thoughtcrime/securesms/dependencies/ApplicationDependencyProvider.java b/app/src/main/java/org/thoughtcrime/securesms/dependencies/ApplicationDependencyProvider.java index d81dc7c46a..93076dea1a 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/dependencies/ApplicationDependencyProvider.java +++ b/app/src/main/java/org/thoughtcrime/securesms/dependencies/ApplicationDependencyProvider.java @@ -175,7 +175,8 @@ public class ApplicationDependencyProvider implements AppDependencies.Provider { SignalExecutors.newCachedBoundedExecutor("signal-messages", ThreadUtil.PRIORITY_IMPORTANT_BACKGROUND_THREAD, 1, 16, 30), RemoteConfig.maxEnvelopeSizeBytes(), RemoteConfig::useMessageSendRestFallback, - RemoteConfig.useBinaryId()); + RemoteConfig.useBinaryId(), + BuildConfig.USE_STRING_ID); } @Override diff --git a/app/src/main/java/org/thoughtcrime/securesms/jobs/MultiDeviceContactUpdateJob.java b/app/src/main/java/org/thoughtcrime/securesms/jobs/MultiDeviceContactUpdateJob.java index c2a07b5e7d..db48d20748 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/jobs/MultiDeviceContactUpdateJob.java +++ b/app/src/main/java/org/thoughtcrime/securesms/jobs/MultiDeviceContactUpdateJob.java @@ -13,6 +13,7 @@ import androidx.annotation.Nullable; import org.signal.core.util.logging.Log; import org.signal.libsignal.protocol.IdentityKey; import org.signal.libsignal.zkgroup.profiles.ProfileKey; +import org.thoughtcrime.securesms.BuildConfig; import org.thoughtcrime.securesms.conversation.colors.ChatColorsMapper; import org.thoughtcrime.securesms.crypto.ProfileKeyUtil; import org.thoughtcrime.securesms.database.RecipientTable; @@ -145,7 +146,7 @@ public class MultiDeviceContactUpdateJob extends BaseJob { Uri updateUri = null; try { - DeviceContactsOutputStream out = new DeviceContactsOutputStream(writeDetails.outputStream, RemoteConfig.useBinaryId()); + DeviceContactsOutputStream out = new DeviceContactsOutputStream(writeDetails.outputStream, RemoteConfig.useBinaryId(), BuildConfig.USE_STRING_ID); Recipient recipient = Recipient.resolved(recipientId); if (recipient.getRegistered() == RecipientTable.RegisteredState.NOT_REGISTERED) { @@ -210,7 +211,7 @@ public class MultiDeviceContactUpdateJob extends BaseJob { Uri updateUri = null; try { - DeviceContactsOutputStream out = new DeviceContactsOutputStream(writeDetails.outputStream, RemoteConfig.useBinaryId()); + DeviceContactsOutputStream out = new DeviceContactsOutputStream(writeDetails.outputStream, RemoteConfig.useBinaryId(), BuildConfig.USE_STRING_ID); List recipients = SignalDatabase.recipients().getRecipientsForMultiDeviceSync(); Map inboxPositions = SignalDatabase.threads().getInboxPositions(); Set archived = SignalDatabase.threads().getArchivedRecipients(); diff --git a/app/src/main/java/org/thoughtcrime/securesms/jobs/MultiDeviceDeleteSyncJob.kt b/app/src/main/java/org/thoughtcrime/securesms/jobs/MultiDeviceDeleteSyncJob.kt index d0d306b760..1ae1c4c0ad 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/jobs/MultiDeviceDeleteSyncJob.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/jobs/MultiDeviceDeleteSyncJob.kt @@ -7,10 +7,12 @@ package org.thoughtcrime.securesms.jobs import androidx.annotation.VisibleForTesting import androidx.annotation.WorkerThread +import okio.ByteString import okio.ByteString.Companion.toByteString import org.signal.core.util.Base64 import org.signal.core.util.logging.Log import org.signal.core.util.orNull +import org.thoughtcrime.securesms.BuildConfig import org.thoughtcrime.securesms.attachments.DatabaseAttachment import org.thoughtcrime.securesms.database.SignalDatabase import org.thoughtcrime.securesms.database.ThreadTable @@ -374,8 +376,16 @@ class MultiDeviceDeleteSyncJob private constructor( private fun Recipient.toDeleteSyncConversationId(): ConversationIdentifier? { return when { isGroup -> ConversationIdentifier(threadGroupId = requireGroupId().decodedId.toByteString()) - hasAci -> ConversationIdentifier(threadServiceId = requireAci().toString()) - hasPni -> ConversationIdentifier(threadServiceId = requirePni().toString()) + hasAci -> if (BuildConfig.USE_STRING_ID) { + ConversationIdentifier(threadServiceId = requireAci().toString()) + } else { + ConversationIdentifier(threadServiceIdBinary = requireAci().toByteString()) + } + hasPni -> if (BuildConfig.USE_STRING_ID) { + ConversationIdentifier(threadServiceId = requirePni().toString()) + } else { + ConversationIdentifier(threadServiceIdBinary = requirePni().toByteString()) + } hasE164 -> ConversationIdentifier(threadE164 = requireE164()) else -> null } @@ -383,7 +393,12 @@ class MultiDeviceDeleteSyncJob private constructor( private fun DeleteSyncJobData.AddressableMessage.toDeleteSyncMessage(): AddressableMessage? { val author: Recipient = Recipient.resolved(RecipientId.from(authorRecipientId)) - val authorServiceId: String? = author.aci.orNull()?.toString() ?: author.pni.orNull()?.toString() + val authorServiceId = if (BuildConfig.USE_STRING_ID) { + author.aci.orNull()?.toString() ?: author.pni.orNull()?.toString() + } else { + author.aci.orNull()?.toByteString() ?: author.pni.orNull()?.toByteString() + } + val authorE164: String? = if (authorServiceId == null) { author.e164.orNull() } else { @@ -394,11 +409,19 @@ class MultiDeviceDeleteSyncJob private constructor( Log.w(TAG, "Unable to send sync message without serviceId or e164 recipient: ${author.id}") null } else { - AddressableMessage( - authorServiceId = authorServiceId, - authorE164 = authorE164, - sentTimestamp = sentTimestamp - ) + if (BuildConfig.USE_STRING_ID) { + AddressableMessage( + authorServiceId = authorServiceId as String?, + authorE164 = authorE164, + sentTimestamp = sentTimestamp + ) + } else { + AddressableMessage( + authorServiceIdBinary = authorServiceId as ByteString?, + authorE164 = authorE164, + sentTimestamp = sentTimestamp + ) + } } } diff --git a/app/src/main/java/org/thoughtcrime/securesms/jobs/MultiDeviceProfileKeyUpdateJob.java b/app/src/main/java/org/thoughtcrime/securesms/jobs/MultiDeviceProfileKeyUpdateJob.java index a51af58e1d..4775d5d12a 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/jobs/MultiDeviceProfileKeyUpdateJob.java +++ b/app/src/main/java/org/thoughtcrime/securesms/jobs/MultiDeviceProfileKeyUpdateJob.java @@ -6,6 +6,7 @@ import androidx.annotation.Nullable; import org.signal.core.util.logging.Log; import org.signal.libsignal.zkgroup.profiles.ProfileKey; +import org.thoughtcrime.securesms.BuildConfig; import org.thoughtcrime.securesms.crypto.ProfileKeyUtil; import org.thoughtcrime.securesms.dependencies.AppDependencies; import org.thoughtcrime.securesms.jobmanager.Job; @@ -72,7 +73,7 @@ public class MultiDeviceProfileKeyUpdateJob extends BaseJob { } ByteArrayOutputStream baos = new ByteArrayOutputStream(); - DeviceContactsOutputStream out = new DeviceContactsOutputStream(baos, RemoteConfig.useBinaryId()); + DeviceContactsOutputStream out = new DeviceContactsOutputStream(baos, RemoteConfig.useBinaryId(), BuildConfig.USE_STRING_ID); out.write(new DeviceContact(Optional.ofNullable(SignalStore.account().getAci()), Optional.ofNullable(SignalStore.account().getE164()), diff --git a/app/src/main/java/org/thoughtcrime/securesms/storage/StorageSyncModels.kt b/app/src/main/java/org/thoughtcrime/securesms/storage/StorageSyncModels.kt index 5ae27ee16e..fbac195955 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/storage/StorageSyncModels.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/storage/StorageSyncModels.kt @@ -7,6 +7,7 @@ import org.signal.core.util.isNullOrEmpty import org.signal.core.util.logging.Log import org.signal.libsignal.zkgroup.InvalidInputException import org.signal.libsignal.zkgroup.groups.GroupMasterKey +import org.thoughtcrime.securesms.BuildConfig import org.thoughtcrime.securesms.components.settings.app.chats.folders.ChatFolderRecord import org.thoughtcrime.securesms.components.settings.app.usernamelinks.UsernameQrCodeColorScheme import org.thoughtcrime.securesms.conversation.colors.AvatarColor @@ -133,7 +134,7 @@ object StorageSyncModels { RecipientType.INDIVIDUAL -> { AccountRecord.PinnedConversation( contact = AccountRecord.PinnedConversation.Contact( - serviceId = settings.serviceId?.toString() ?: "", + serviceId = settings.serviceId?.toString().takeIf { BuildConfig.USE_STRING_ID } ?: "", e164 = settings.e164 ?: "", serviceIdBinary = settings.serviceId?.toByteString().takeIf { RemoteConfig.useBinaryId } ?: ByteString.EMPTY ) @@ -188,9 +189,9 @@ object StorageSyncModels { } return SignalContactRecord.newBuilder(recipient.syncExtras.storageProto).apply { - aci = recipient.aci?.toString() ?: "" + aci = recipient.aci?.toString().takeIf { BuildConfig.USE_STRING_ID } ?: "" e164 = recipient.e164 ?: "" - pni = recipient.pni?.toStringWithoutPrefix() ?: "" + pni = recipient.pni?.toStringWithoutPrefix().takeIf { BuildConfig.USE_STRING_ID } ?: "" profileKey = recipient.profileKey?.toByteString() ?: ByteString.EMPTY givenName = recipient.signalProfileName.givenName familyName = recipient.signalProfileName.familyName @@ -294,10 +295,14 @@ object StorageSyncModels { return SignalStoryDistributionListRecord.newBuilder(recipient.syncExtras.storageProto).apply { identifier = UuidUtil.toByteArray(record.distributionId.asUuid()).toByteString() name = record.name - recipientServiceIds = record.getMembersToSync() - .map { Recipient.resolved(it) } - .filter { it.hasServiceId } - .map { it.requireServiceId().toString() } + recipientServiceIds = if (BuildConfig.USE_STRING_ID) { + record.getMembersToSync() + .map { Recipient.resolved(it) } + .filter { it.hasServiceId } + .map { it.requireServiceId().toString() } + } else { + emptyList() + } recipientServiceIdsBinary = if (RemoteConfig.useBinaryId) { record.getMembersToSync() .map { Recipient.resolved(it) } @@ -507,7 +512,7 @@ object StorageSyncModels { RecipientType.INDIVIDUAL -> { RemoteRecipient( contact = RemoteRecipient.Contact( - serviceId = recipient.serviceId?.toString() ?: "", + serviceId = recipient.serviceId?.toString().takeIf { BuildConfig.USE_STRING_ID } ?: "", e164 = recipient.e164 ?: "", serviceIdBinary = recipient.serviceId?.toByteString().takeIf { RemoteConfig.useBinaryId } ?: ByteString.EMPTY ) diff --git a/app/src/main/java/org/thoughtcrime/securesms/util/RemoteConfig.kt b/app/src/main/java/org/thoughtcrime/securesms/util/RemoteConfig.kt index 351c402573..b6682288d4 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/util/RemoteConfig.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/util/RemoteConfig.kt @@ -1186,7 +1186,7 @@ object RemoteConfig { @get:JvmName("useBinaryId") val useBinaryId: Boolean by remoteBoolean( key = "android.useBinaryServiceId", - defaultValue = false, + defaultValue = Environment.IS_STAGING, hotSwappable = false ) diff --git a/libsignal-service/src/main/java/org/whispersystems/signalservice/api/SignalServiceMessageSender.java b/libsignal-service/src/main/java/org/whispersystems/signalservice/api/SignalServiceMessageSender.java index d80c7bc9d4..0bf2018b84 100644 --- a/libsignal-service/src/main/java/org/whispersystems/signalservice/api/SignalServiceMessageSender.java +++ b/libsignal-service/src/main/java/org/whispersystems/signalservice/api/SignalServiceMessageSender.java @@ -185,6 +185,7 @@ public class SignalServiceMessageSender { private final long maxEnvelopeSize; private final BooleanSupplier useRestFallback; private final boolean useBinaryId; + private final boolean useStringId; public SignalServiceMessageSender(PushServiceSocket pushServiceSocket, SignalServiceDataStore store, @@ -196,7 +197,8 @@ public class SignalServiceMessageSender { ExecutorService executor, long maxEnvelopeSize, BooleanSupplier useRestFallback, - boolean useBinaryId) + boolean useBinaryId, + boolean useStringId) { CredentialsProvider credentialsProvider = pushServiceSocket.getCredentialsProvider(); @@ -215,6 +217,7 @@ public class SignalServiceMessageSender { this.keysApi = keysApi; this.useRestFallback = useRestFallback; this.useBinaryId = useBinaryId; + this.useStringId = useStringId; } /** @@ -1059,7 +1062,7 @@ public class SignalServiceMessageSender { DataMessage.Quote.Builder quoteBuilder = new DataMessage.Quote.Builder() .id(message.getQuote().get().getId()) .text(message.getQuote().get().getText()) - .authorAci(message.getQuote().get().getAuthor().toString()) + .authorAci(useStringId ? message.getQuote().get().getAuthor().toString() : null) .authorAciBinary(useBinaryId ? message.getQuote().get().getAuthor().toByteString() : null) .type(message.getQuote().get().getType().getProtoType()); @@ -1067,11 +1070,19 @@ public class SignalServiceMessageSender { if (mentions != null && !mentions.isEmpty()) { List bodyRanges = new ArrayList<>(quoteBuilder.bodyRanges); for (SignalServiceDataMessage.Mention mention : mentions) { - bodyRanges.add(new BodyRange.Builder() - .start(mention.getStart()) - .length(mention.getLength()) - .mentionAci(mention.getServiceId().toString()) - .build()); + if (useStringId) { + bodyRanges.add(new BodyRange.Builder() + .start(mention.getStart()) + .length(mention.getLength()) + .mentionAci(mention.getServiceId().toString()) + .build()); + } else { + bodyRanges.add(new BodyRange.Builder() + .start(mention.getStart()) + .length(mention.getLength()) + .mentionAciBinary(mention.getServiceId().toByteString()) + .build()); + } } quoteBuilder.bodyRanges(bodyRanges); @@ -1128,11 +1139,19 @@ public class SignalServiceMessageSender { if (message.getMentions().isPresent()) { List bodyRanges = new ArrayList<>(builder.bodyRanges); for (SignalServiceDataMessage.Mention mention : message.getMentions().get()) { - bodyRanges.add(new BodyRange.Builder() - .start(mention.getStart()) - .length(mention.getLength()) - .mentionAci(mention.getServiceId().toString()) - .build()); + if (useStringId) { + bodyRanges.add(new BodyRange.Builder() + .start(mention.getStart()) + .length(mention.getLength()) + .mentionAci(mention.getServiceId().toString()) + .build()); + } else { + bodyRanges.add(new BodyRange.Builder() + .start(mention.getStart()) + .length(mention.getLength()) + .mentionAciBinary(mention.getServiceId().toByteString()) + .build()); + } } builder.bodyRanges(bodyRanges); builder.requiredProtocolVersion(Math.max(DataMessage.ProtocolVersion.MENTIONS.getValue(), builder.requiredProtocolVersion)); @@ -1168,7 +1187,7 @@ public class SignalServiceMessageSender { .emoji(message.getReaction().get().getEmoji()) .remove(message.getReaction().get().isRemove()) .targetSentTimestamp(message.getReaction().get().getTargetSentTimestamp()) - .targetAuthorAci(message.getReaction().get().getTargetAuthor().toString()) + .targetAuthorAci(useStringId ? message.getReaction().get().getTargetAuthor().toString() : null) .targetAuthorAciBinary(useBinaryId ? message.getReaction().get().getTargetAuthor().toByteString() : null); builder.reaction(reactionBuilder.build()); @@ -1213,7 +1232,7 @@ public class SignalServiceMessageSender { SignalServiceDataMessage.StoryContext storyContext = message.getStoryContext().get(); builder.storyContext(new DataMessage.StoryContext.Builder() - .authorAci(storyContext.getAuthorServiceId().toString()) + .authorAci(useStringId ? storyContext.getAuthorServiceId().toString() : null) .authorAciBinary(useBinaryId ? storyContext.getAuthorServiceId().toByteString() : null) .sentTimestamp(storyContext.getSentTimestamp()) .build()); @@ -1404,7 +1423,7 @@ public class SignalServiceMessageSender { } unidentifiedDeliveryStatuses.add(new SyncMessage.Sent.UnidentifiedDeliveryStatus.Builder() - .destinationServiceId(result.getAddress().getServiceId().toString()) + .destinationServiceId(useStringId ? result.getAddress().getServiceId().toString() : null) .destinationServiceIdBinary(useBinaryId ? result.getAddress().getServiceId().toByteString() : null) .unidentified(false) .destinationPniIdentityKey(identity) @@ -1414,7 +1433,7 @@ public class SignalServiceMessageSender { sentMessage.unidentifiedStatus(unidentifiedDeliveryStatuses); if (recipient.isPresent()) { - sentMessage.destinationServiceId(recipient.get().getServiceId().toString()); + sentMessage.destinationServiceId(useStringId ? recipient.get().getServiceId().toString() : null); sentMessage.destinationServiceIdBinary(useBinaryId ? recipient.get().getServiceId().toByteString() : null); if (recipient.get().getNumber().isPresent()) { sentMessage.destinationE164(recipient.get().getNumber().get()); @@ -1454,7 +1473,7 @@ public class SignalServiceMessageSender { private SyncMessage.Sent.StoryMessageRecipient createStoryMessageRecipient(SignalServiceStoryMessageRecipient storyMessageRecipient) { return new SyncMessage.Sent.StoryMessageRecipient.Builder() .distributionListIds(storyMessageRecipient.getDistributionListIds()) - .destinationServiceId(storyMessageRecipient.getSignalServiceAddress().getIdentifier()) + .destinationServiceId(useStringId ? storyMessageRecipient.getSignalServiceAddress().getIdentifier() : null) .destinationServiceIdBinary(useBinaryId ? storyMessageRecipient.getSignalServiceAddress().getServiceId().toByteString() : null) .isAllowedToReply(storyMessageRecipient.isAllowedToReply()) .build(); @@ -1468,7 +1487,7 @@ public class SignalServiceMessageSender { readMessages.stream() .map(readMessage -> new SyncMessage.Read.Builder() .timestamp(readMessage.getTimestamp()) - .senderAci(readMessage.getSenderAci().toString()) + .senderAci(useStringId ? readMessage.getSenderAci().toString() : null) .senderAciBinary(useBinaryId ? readMessage.getSenderAci().toByteString() : null) .build()) .collect(Collectors.toList()) @@ -1485,7 +1504,7 @@ public class SignalServiceMessageSender { readMessages.stream() .map(readMessage -> new SyncMessage.Viewed.Builder() .timestamp(readMessage.getTimestamp()) - .senderAci(readMessage.getSender().toString()) + .senderAci(useStringId ? readMessage.getSender().toString() : null) .senderAciBinary(useBinaryId ? readMessage.getSender().toByteString() : null) .build()) .collect(Collectors.toList()) @@ -1500,7 +1519,7 @@ public class SignalServiceMessageSender { builder.viewOnceOpen(new SyncMessage.ViewOnceOpen.Builder() .timestamp(readMessage.getTimestamp()) - .senderAci(readMessage.getSender().toString()) + .senderAci(useStringId ? readMessage.getSender().toString() : null) .senderAciBinary(useBinaryId ? readMessage.getSender().toByteString() : null) .build()); @@ -1512,7 +1531,7 @@ public class SignalServiceMessageSender { SyncMessage.Builder syncMessage = createSyncMessageBuilder(); SyncMessage.Blocked.Builder blockedMessage = new SyncMessage.Blocked.Builder(); - blockedMessage.acis(blocked.individuals.stream().filter(a -> a.getAci() != null).map(a -> a.getAci().toString()).collect(Collectors.toList())); + blockedMessage.acis(useStringId ? blocked.individuals.stream().filter(a -> a.getAci() != null).map(a -> a.getAci().toString()).collect(Collectors.toList()) : Collections.emptyList()); blockedMessage.acisBinary(useBinaryId ? blocked.individuals.stream().filter(a -> a.getAci() != null).map(a -> a.getAci().toByteString()).collect(Collectors.toList()) : Collections.emptyList()); blockedMessage.numbers(blocked.individuals.stream().filter(a -> a.getE164() != null).map(a -> a.getE164()).collect(Collectors.toList())); blockedMessage.groupIds(blocked.groupIds.stream().map(ByteString::of).collect(Collectors.toList())); @@ -1612,7 +1631,7 @@ public class SignalServiceMessageSender { } if (message.getPerson().isPresent()) { - responseMessage.threadAci(message.getPerson().get().toString()); + responseMessage.threadAci(useStringId ? message.getPerson().get().toString() : null); responseMessage.threadAciBinary(useBinaryId ? message.getPerson().get().toByteString() : null); } @@ -1710,7 +1729,7 @@ public class SignalServiceMessageSender { verifiedMessageBuilder.nullMessage(ByteString.of(nullMessage)); verifiedMessageBuilder.identityKey(ByteString.of(verifiedMessage.getIdentityKey().serialize())); - verifiedMessageBuilder.destinationAci(verifiedMessage.getDestination().getServiceId().toString()); + verifiedMessageBuilder.destinationAci(useStringId ? verifiedMessage.getDestination().getServiceId().toString() : null); verifiedMessageBuilder.destinationAciBinary(useBinaryId ? verifiedMessage.getDestination().getServiceId().toByteString() : null); diff --git a/libsignal-service/src/main/java/org/whispersystems/signalservice/api/messages/multidevice/DeviceContactsOutputStream.java b/libsignal-service/src/main/java/org/whispersystems/signalservice/api/messages/multidevice/DeviceContactsOutputStream.java index 99ecb285fe..ca851cd5d5 100644 --- a/libsignal-service/src/main/java/org/whispersystems/signalservice/api/messages/multidevice/DeviceContactsOutputStream.java +++ b/libsignal-service/src/main/java/org/whispersystems/signalservice/api/messages/multidevice/DeviceContactsOutputStream.java @@ -17,10 +17,12 @@ import okio.ByteString; public class DeviceContactsOutputStream extends ChunkedOutputStream { private final boolean useBinaryId; + private final boolean useStringId; - public DeviceContactsOutputStream(OutputStream out, boolean useBinaryId) { + public DeviceContactsOutputStream(OutputStream out, boolean useBinaryId, boolean useStringId) { super(out); this.useBinaryId = useBinaryId; + this.useStringId = useStringId; } public void write(DeviceContact contact) throws IOException { @@ -42,7 +44,7 @@ public class DeviceContactsOutputStream extends ChunkedOutputStream { ContactDetails.Builder contactDetails = new ContactDetails.Builder(); if (contact.getAci().isPresent()) { - contactDetails.aci(contact.getAci().get().toString()); + contactDetails.aci(useStringId ? contact.getAci().get().toString() : null); contactDetails.aciBinary(useBinaryId ? contact.getAci().get().toByteString() : null); } diff --git a/libsignal-service/src/test/java/org/whispersystems/signalservice/api/messages/multidevice/DeviceContactsInputStreamTest.java b/libsignal-service/src/test/java/org/whispersystems/signalservice/api/messages/multidevice/DeviceContactsInputStreamTest.java index 0be32f845a..bb08a13acf 100644 --- a/libsignal-service/src/test/java/org/whispersystems/signalservice/api/messages/multidevice/DeviceContactsInputStreamTest.java +++ b/libsignal-service/src/test/java/org/whispersystems/signalservice/api/messages/multidevice/DeviceContactsInputStreamTest.java @@ -17,7 +17,7 @@ public class DeviceContactsInputStreamTest { @Test public void read() throws IOException, InvalidInputException { ByteArrayOutputStream byteArrayOut = new ByteArrayOutputStream(); - DeviceContactsOutputStream output = new DeviceContactsOutputStream(byteArrayOut, true); + DeviceContactsOutputStream output = new DeviceContactsOutputStream(byteArrayOut, true, true); Optional aciFirst = Optional.of(ACI.from(UUID.randomUUID())); Optional e164First = Optional.of("+1404555555"); Optional aciSecond = Optional.of(ACI.from(UUID.randomUUID()));