From 5bb48caafd846a1699caa26e61589573375b5ad6 Mon Sep 17 00:00:00 2001 From: Greyson Parrelli Date: Thu, 28 Oct 2021 15:39:36 -0400 Subject: [PATCH] Strongly type UUIDs as ACIs. --- .../database/RecipientDatabaseTest.kt | 71 +++--- .../database/RecipientDatabaseTest_merges.kt | 9 +- .../ContactSelectionListFragment.java | 3 +- .../securesms/NewConversationActivity.java | 2 +- .../securesms/VerifyIdentityActivity.java | 24 +- .../InternalConversationSettingsFragment.kt | 8 +- .../webrtc/CallParticipantsState.kt | 4 +- .../contacts/sync/ContactDiscoveryV2.java | 3 +- .../contacts/sync/ContactDiscoveryV3.java | 3 +- .../contacts/sync/DirectoryHelper.java | 52 ++-- .../contacts/sync/FuzzyPhoneNumberHelper.java | 12 +- .../conversation/ConversationActivity.java | 9 +- .../conversation/ConversationUpdateItem.java | 9 +- .../storage/TextSecureIdentityKeyStore.java | 4 +- .../storage/TextSecureSessionStore.java | 4 +- .../securesms/database/GroupDatabase.java | 37 +-- .../securesms/database/MentionUtil.java | 5 +- .../securesms/database/MmsDatabase.java | 3 +- .../securesms/database/RecipientDatabase.java | 227 +++++++++--------- .../database/SenderKeySharedDatabase.java | 4 +- .../securesms/database/SmsDatabase.java | 8 +- .../securesms/database/ThreadDatabase.java | 3 +- .../model/GroupCallUpdateMessageFactory.java | 23 +- .../model/GroupsV2UpdateMessageProducer.java | 16 +- .../database/model/MessageRecord.java | 24 +- .../database/model/UpdateDescription.java | 23 +- .../ApplicationDependencyProvider.java | 6 +- .../securesms/groups/GroupManagerV2.java | 61 ++--- .../securesms/groups/GroupProtoUtil.java | 14 +- .../groups/GroupsV1MigrationUtil.java | 6 +- .../groups/GroupsV2Authorization.java | 5 +- .../groups/GroupsV2CapabilityChecker.java | 2 +- .../securesms/groups/LiveGroup.java | 3 +- .../PendingMemberInvitesRepository.java | 2 +- .../GroupsV1MigrationRepository.java | 5 +- .../groups/v2/GroupCandidateHelper.java | 9 +- .../securesms/groups/v2/ProfileKeySet.java | 17 +- .../v2/processing/GroupsV2StateProcessor.java | 35 +-- .../securesms/jobs/GroupV1MigrationJob.java | 3 +- .../securesms/jobs/MmsDownloadJob.java | 2 +- .../jobs/MultiDeviceBlockedUpdateJob.java | 2 +- .../MultiDeviceOutgoingPaymentSyncJob.java | 5 +- .../jobs/PushGroupSilentUpdateSendJob.java | 5 +- .../securesms/jobs/PushMediaSendJob.java | 2 +- .../securesms/jobs/PushSendJob.java | 11 +- .../securesms/jobs/PushTextSendJob.java | 2 +- .../securesms/jobs/RetrieveProfileJob.java | 18 +- .../securesms/jobs/SmsReceiveJob.java | 2 +- .../logsubmit/LogSectionCapabilities.java | 2 +- .../logsubmit/LogSectionKeyPreferences.java | 2 +- .../logsubmit/LogSectionSystemInfo.java | 16 +- .../securesms/messages/GroupSendUtil.java | 10 +- .../messages/MessageContentProcessor.java | 17 +- .../messages/MessageDecryptionUtil.java | 2 +- .../migrations/AccountRecordMigrationJob.java | 2 +- .../ApplyUnknownFieldsToSelfMigrationJob.java | 4 +- .../DirectoryRefreshMigrationJob.java | 2 +- .../StorageServiceMigrationJob.java | 2 +- .../UserNotificationMigrationJob.java | 2 +- .../migrations/UuidMigrationJob.java | 5 +- .../securesms/mms/MessageGroupContext.java | 3 +- .../securesms/push/AccountManagerFactory.java | 9 +- .../recipients/LiveRecipientCache.java | 7 +- .../securesms/recipients/Recipient.java | 71 +++--- .../recipients/RecipientDetails.java | 14 +- .../securesms/recipients/RecipientId.java | 17 +- .../recipients/RecipientIdCache.java | 25 +- .../securesms/recipients/RecipientUtil.java | 13 +- .../registration/RegistrationRepository.java | 12 +- .../service/webrtc/GroupActionProcessor.java | 3 +- .../webrtc/GroupConnectedActionProcessor.java | 6 +- .../webrtc/GroupPreJoinActionProcessor.java | 3 +- .../IncomingGroupCallActionProcessor.java | 3 +- .../service/webrtc/SignalCallManager.java | 5 +- .../storage/ContactRecordProcessor.java | 13 +- .../securesms/storage/StorageSyncModels.java | 9 +- .../storage/StorageSyncValidations.java | 5 +- .../securesms/util/BucketingUtil.java | 2 +- .../securesms/util/CommunicationActions.java | 2 +- .../securesms/util/LocaleFeatureFlags.java | 4 +- .../securesms/util/ProfileUtil.java | 6 +- .../securesms/util/RecipientAccessList.kt | 14 +- .../securesms/util/TextSecurePreferences.java | 12 +- .../securesms/util/UsernameUtil.java | 10 +- .../sync/FuzzyPhoneNumberHelperTest.java | 36 +-- .../database/RecipientDatabaseTestUtils.kt | 5 +- .../GroupsV2UpdateMessageProducerTest.java | 11 +- .../database/model/UpdateDescriptionTest.java | 17 +- .../groups/v2/ProfileKeySetTest.java | 25 +- .../recipients/RecipientIdCacheTest.java | 99 ++++---- .../storage/StorageSyncHelperTest.java | 104 +------- .../api/SignalServiceAccountManager.java | 51 ++-- .../api/SignalServiceMessageReceiver.java | 9 +- .../api/SignalServiceMessageSender.java | 53 ++-- .../api/crypto/SignalServiceCipher.java | 9 +- .../api/groupsv2/GroupsV2Api.java | 5 +- .../api/messages/SignalServiceContent.java | 29 +-- .../messages/SignalServiceDataMessage.java | 15 +- .../api/messages/SignalServiceEnvelope.java | 5 +- .../DeviceContactsInputStream.java | 5 +- .../DeviceContactsOutputStream.java | 4 +- .../multidevice/OutgoingPaymentMessage.java | 25 +- .../multidevice/SentTranscriptMessage.java | 19 +- .../api/profiles/SignalServiceProfile.java | 9 +- .../signalservice/api/push/ACI.java | 112 +++++++++ .../api/push/SignalServiceAddress.java | 37 ++- .../api/services/CdshService.java | 15 +- .../api/services/ProfileService.java | 13 +- .../api/storage/SignalAccountRecord.java | 5 +- .../api/storage/SignalContactRecord.java | 7 +- .../api/util/CredentialsProvider.java | 8 +- .../signalservice/api/util/UuidUtil.java | 2 +- .../internal/push/PushServiceSocket.java | 11 +- .../push/SendGroupMessageResponse.java | 11 +- ...ignalServiceAddressProtobufSerializer.java | 12 +- .../signalservice/internal/util/JsonUtil.java | 17 ++ .../util/StaticCredentialsProvider.java | 17 +- .../websocket/WebSocketConnection.java | 2 +- .../api/storage/SignalContactRecordTest.java | 17 +- ...lServiceAddressProtobufSerializerTest.java | 5 +- 120 files changed, 1020 insertions(+), 947 deletions(-) create mode 100644 libsignal/service/src/main/java/org/whispersystems/signalservice/api/push/ACI.java diff --git a/app/src/androidTest/java/org/thoughtcrime/securesms/database/RecipientDatabaseTest.kt b/app/src/androidTest/java/org/thoughtcrime/securesms/database/RecipientDatabaseTest.kt index e89d54198c..9e0361beed 100644 --- a/app/src/androidTest/java/org/thoughtcrime/securesms/database/RecipientDatabaseTest.kt +++ b/app/src/androidTest/java/org/thoughtcrime/securesms/database/RecipientDatabaseTest.kt @@ -13,6 +13,7 @@ import org.junit.runner.RunWith import org.thoughtcrime.securesms.recipients.Recipient import org.thoughtcrime.securesms.recipients.RecipientId import org.whispersystems.libsignal.util.guava.Optional +import org.whispersystems.signalservice.api.push.ACI import java.lang.IllegalArgumentException import java.util.UUID @@ -37,7 +38,7 @@ class RecipientDatabaseTest { val recipientId: RecipientId = recipientDatabase.getAndPossiblyMerge(ACI_A, null, true) val recipient = Recipient.resolved(recipientId) - assertEquals(ACI_A, recipient.requireUuid()) + assertEquals(ACI_A, recipient.requireAci()) assertFalse(recipient.hasE164()) } @@ -47,7 +48,7 @@ class RecipientDatabaseTest { val recipientId: RecipientId = recipientDatabase.getAndPossiblyMerge(ACI_A, null, false) val recipient = Recipient.resolved(recipientId) - assertEquals(ACI_A, recipient.requireUuid()) + assertEquals(ACI_A, recipient.requireAci()) assertFalse(recipient.hasE164()) } @@ -58,7 +59,7 @@ class RecipientDatabaseTest { val recipient = Recipient.resolved(recipientId) assertEquals(E164_A, recipient.requireE164()) - assertFalse(recipient.hasUuid()) + assertFalse(recipient.hasAci()) } /** If all you have is an E164, you can just store that, regardless of trust level. */ @@ -68,7 +69,7 @@ class RecipientDatabaseTest { val recipient = Recipient.resolved(recipientId) assertEquals(E164_A, recipient.requireE164()) - assertFalse(recipient.hasUuid()) + assertFalse(recipient.hasAci()) } /** With high trust, you can associate an ACI-e164 pair. */ @@ -77,7 +78,7 @@ class RecipientDatabaseTest { val recipientId: RecipientId = recipientDatabase.getAndPossiblyMerge(ACI_A, E164_A, true) val recipient = Recipient.resolved(recipientId) - assertEquals(ACI_A, recipient.requireUuid()) + assertEquals(ACI_A, recipient.requireAci()) assertEquals(E164_A, recipient.requireE164()) } @@ -87,7 +88,7 @@ class RecipientDatabaseTest { val recipientId: RecipientId = recipientDatabase.getAndPossiblyMerge(ACI_A, E164_A, false) val recipient = Recipient.resolved(recipientId) - assertEquals(ACI_A, recipient.requireUuid()) + assertEquals(ACI_A, recipient.requireAci()) assertFalse(recipient.hasE164()) } @@ -98,26 +99,26 @@ class RecipientDatabaseTest { /** With high trust, you can associate an e164 with an existing ACI. */ @Test fun getAndPossiblyMerge_aciMapsToExistingUserButE164DoesNot_aciAndE164_highTrust() { - val existingId: RecipientId = recipientDatabase.getOrInsertFromUuid(ACI_A) + val existingId: RecipientId = recipientDatabase.getOrInsertFromAci(ACI_A) val retrievedId: RecipientId = recipientDatabase.getAndPossiblyMerge(ACI_A, E164_A, true) assertEquals(existingId, retrievedId) val retrievedRecipient = Recipient.resolved(retrievedId) - assertEquals(ACI_A, retrievedRecipient.requireUuid()) + assertEquals(ACI_A, retrievedRecipient.requireAci()) assertEquals(E164_A, retrievedRecipient.requireE164()) } /** With low trust, you cannot associate an ACI-e164 pair, and therefore cannot store the e164. */ @Test fun getAndPossiblyMerge_aciMapsToExistingUserButE164DoesNot_aciAndE164_lowTrust() { - val existingId: RecipientId = recipientDatabase.getOrInsertFromUuid(ACI_A) + val existingId: RecipientId = recipientDatabase.getOrInsertFromAci(ACI_A) val retrievedId: RecipientId = recipientDatabase.getAndPossiblyMerge(ACI_A, E164_A, false) assertEquals(existingId, retrievedId) val retrievedRecipient = Recipient.resolved(retrievedId) - assertEquals(ACI_A, retrievedRecipient.requireUuid()) + assertEquals(ACI_A, retrievedRecipient.requireAci()) assertFalse(retrievedRecipient.hasE164()) } @@ -130,7 +131,7 @@ class RecipientDatabaseTest { assertEquals(existingId, retrievedId) val retrievedRecipient = Recipient.resolved(retrievedId) - assertEquals(ACI_A, retrievedRecipient.requireUuid()) + assertEquals(ACI_A, retrievedRecipient.requireAci()) assertEquals(E164_B, retrievedRecipient.requireE164()) } @@ -143,7 +144,7 @@ class RecipientDatabaseTest { assertEquals(existingId, retrievedId) val retrievedRecipient = Recipient.resolved(retrievedId) - assertEquals(ACI_A, retrievedRecipient.requireUuid()) + assertEquals(ACI_A, retrievedRecipient.requireAci()) assertEquals(E164_A, retrievedRecipient.requireE164()) } @@ -160,7 +161,7 @@ class RecipientDatabaseTest { assertEquals(existingId, retrievedId) val retrievedRecipient = Recipient.resolved(retrievedId) - assertEquals(ACI_A, retrievedRecipient.requireUuid()) + assertEquals(ACI_A, retrievedRecipient.requireAci()) assertEquals(E164_A, retrievedRecipient.requireE164()) } @@ -173,12 +174,12 @@ class RecipientDatabaseTest { assertNotEquals(existingId, retrievedId) val retrievedRecipient = Recipient.resolved(retrievedId) - assertEquals(ACI_A, retrievedRecipient.requireUuid()) + assertEquals(ACI_A, retrievedRecipient.requireAci()) assertFalse(retrievedRecipient.hasE164()) val existingRecipient = Recipient.resolved(existingId) assertEquals(E164_A, existingRecipient.requireE164()) - assertFalse(existingRecipient.hasUuid()) + assertFalse(existingRecipient.hasAci()) } /** We never change the ACI of an existing row. New ACI = new person, regardless of trust. But high trust lets us take the e164 from the current holder. */ @@ -190,11 +191,11 @@ class RecipientDatabaseTest { assertNotEquals(existingId, retrievedId) val retrievedRecipient = Recipient.resolved(retrievedId) - assertEquals(ACI_B, retrievedRecipient.requireUuid()) + assertEquals(ACI_B, retrievedRecipient.requireAci()) assertEquals(E164_A, retrievedRecipient.requireE164()) val existingRecipient = Recipient.resolved(existingId) - assertEquals(ACI_A, existingRecipient.requireUuid()) + assertEquals(ACI_A, existingRecipient.requireAci()) assertFalse(existingRecipient.hasE164()) } @@ -207,11 +208,11 @@ class RecipientDatabaseTest { assertNotEquals(existingId, retrievedId) val retrievedRecipient = Recipient.resolved(retrievedId) - assertEquals(ACI_B, retrievedRecipient.requireUuid()) + assertEquals(ACI_B, retrievedRecipient.requireAci()) assertFalse(retrievedRecipient.hasE164()) val existingRecipient = Recipient.resolved(existingId) - assertEquals(ACI_A, existingRecipient.requireUuid()) + assertEquals(ACI_A, existingRecipient.requireAci()) assertEquals(E164_A, existingRecipient.requireE164()) } @@ -228,21 +229,21 @@ class RecipientDatabaseTest { assertEquals(existingId, retrievedId) val retrievedRecipient = Recipient.resolved(retrievedId) - assertEquals(ACI_A, retrievedRecipient.requireUuid()) + assertEquals(ACI_A, retrievedRecipient.requireAci()) assertEquals(E164_A, retrievedRecipient.requireE164()) } /** High trust lets you merge two different users into one. You should prefer the ACI user. Not shown: merging threads, dropping e164 sessions, etc. */ @Test fun getAndPossiblyMerge_bothAciAndE164MapToExistingUser_aciAndE164_merge_highTrust() { - val existingAciId: RecipientId = recipientDatabase.getOrInsertFromUuid(ACI_A) + val existingAciId: RecipientId = recipientDatabase.getOrInsertFromAci(ACI_A) val existingE164Id: RecipientId = recipientDatabase.getOrInsertFromE164(E164_A) val retrievedId: RecipientId = recipientDatabase.getAndPossiblyMerge(ACI_A, E164_A, true) assertEquals(existingAciId, retrievedId) val retrievedRecipient = Recipient.resolved(retrievedId) - assertEquals(ACI_A, retrievedRecipient.requireUuid()) + assertEquals(ACI_A, retrievedRecipient.requireAci()) assertEquals(E164_A, retrievedRecipient.requireE164()) val existingE164Recipient = Recipient.resolved(existingE164Id) @@ -252,19 +253,19 @@ class RecipientDatabaseTest { /** Low trust means you can’t merge. If you’re retrieving a user from the table with this data, prefer the ACI one. */ @Test fun getAndPossiblyMerge_bothAciAndE164MapToExistingUser_aciAndE164_lowTrust() { - val existingAciId: RecipientId = recipientDatabase.getOrInsertFromUuid(ACI_A) + val existingAciId: RecipientId = recipientDatabase.getOrInsertFromAci(ACI_A) val existingE164Id: RecipientId = recipientDatabase.getOrInsertFromE164(E164_A) val retrievedId: RecipientId = recipientDatabase.getAndPossiblyMerge(ACI_A, E164_A, false) assertEquals(existingAciId, retrievedId) val retrievedRecipient = Recipient.resolved(retrievedId) - assertEquals(ACI_A, retrievedRecipient.requireUuid()) + assertEquals(ACI_A, retrievedRecipient.requireAci()) assertFalse(retrievedRecipient.hasE164()) val existingE164Recipient = Recipient.resolved(existingE164Id) assertEquals(E164_A, existingE164Recipient.requireE164()) - assertFalse(existingE164Recipient.hasUuid()) + assertFalse(existingE164Recipient.hasAci()) } /** Another high trust case. No new rules here, just a more complex scenario to show how different rules interact. */ @@ -277,11 +278,11 @@ class RecipientDatabaseTest { assertEquals(existingId1, retrievedId) val retrievedRecipient = Recipient.resolved(retrievedId) - assertEquals(ACI_A, retrievedRecipient.requireUuid()) + assertEquals(ACI_A, retrievedRecipient.requireAci()) assertEquals(E164_A, retrievedRecipient.requireE164()) val existingRecipient2 = Recipient.resolved(existingId2) - assertEquals(ACI_B, existingRecipient2.requireUuid()) + assertEquals(ACI_B, existingRecipient2.requireAci()) assertFalse(existingRecipient2.hasE164()) } @@ -295,11 +296,11 @@ class RecipientDatabaseTest { assertEquals(existingId1, retrievedId) val retrievedRecipient = Recipient.resolved(retrievedId) - assertEquals(ACI_A, retrievedRecipient.requireUuid()) + assertEquals(ACI_A, retrievedRecipient.requireAci()) assertEquals(E164_B, retrievedRecipient.requireE164()) val existingRecipient2 = Recipient.resolved(existingId2) - assertEquals(ACI_B, existingRecipient2.requireUuid()) + assertEquals(ACI_B, existingRecipient2.requireAci()) assertEquals(E164_A, existingRecipient2.requireE164()) } @@ -327,18 +328,18 @@ class RecipientDatabaseTest { @Test fun createByUuidSanityCheck() { // GIVEN one recipient - val recipientId: RecipientId = recipientDatabase.getOrInsertFromUuid(ACI_A) + val recipientId: RecipientId = recipientDatabase.getOrInsertFromAci(ACI_A) // WHEN I retrieve one by UUID - val possible: Optional = recipientDatabase.getByUuid(ACI_A) + val possible: Optional = recipientDatabase.getByAci(ACI_A) // THEN I get it back, and it has the properties I expect assertTrue(possible.isPresent) assertEquals(recipientId, possible.get()) val recipient = Recipient.resolved(recipientId) - assertTrue(recipient.uuid.isPresent) - assertEquals(ACI_A, recipient.uuid.get()) + assertTrue(recipient.aci.isPresent) + assertEquals(ACI_A, recipient.aci.get()) } @Test(expected = IllegalArgumentException::class) @@ -357,8 +358,8 @@ class RecipientDatabaseTest { } companion object { - val ACI_A = UUID.fromString("3436efbe-5a76-47fa-a98a-7e72c948a82e") - val ACI_B = UUID.fromString("8de7f691-0b60-4a68-9cd9-ed2f8453f9ed") + val ACI_A = ACI.from(UUID.fromString("3436efbe-5a76-47fa-a98a-7e72c948a82e")) + val ACI_B = ACI.from(UUID.fromString("8de7f691-0b60-4a68-9cd9-ed2f8453f9ed")) val E164_A = "+12221234567" val E164_B = "+13331234567" diff --git a/app/src/androidTest/java/org/thoughtcrime/securesms/database/RecipientDatabaseTest_merges.kt b/app/src/androidTest/java/org/thoughtcrime/securesms/database/RecipientDatabaseTest_merges.kt index a007a2cc3d..a99f0da5b0 100644 --- a/app/src/androidTest/java/org/thoughtcrime/securesms/database/RecipientDatabaseTest_merges.kt +++ b/app/src/androidTest/java/org/thoughtcrime/securesms/database/RecipientDatabaseTest_merges.kt @@ -27,6 +27,7 @@ import org.whispersystems.libsignal.IdentityKey import org.whispersystems.libsignal.SignalProtocolAddress import org.whispersystems.libsignal.state.SessionRecord import org.whispersystems.libsignal.util.guava.Optional +import org.whispersystems.signalservice.api.push.ACI import org.whispersystems.signalservice.api.util.UuidUtil import java.util.UUID @@ -62,7 +63,7 @@ class RecipientDatabaseTest_merges { @Test fun getAndPossiblyMerge_general() { // Setup - val recipientIdAci: RecipientId = recipientDatabase.getOrInsertFromUuid(ACI_A) + val recipientIdAci: RecipientId = recipientDatabase.getOrInsertFromAci(ACI_A) val recipientIdE164: RecipientId = recipientDatabase.getOrInsertFromE164(E164_A) val smsId1: Long = smsDatabase.insertMessageInbox(smsMessage(sender = recipientIdAci, time = 0, body = "0")).get().messageId @@ -97,7 +98,7 @@ class RecipientDatabaseTest_merges { // Recipient validation val retrievedRecipient = Recipient.resolved(retrievedId) - assertEquals(ACI_A, retrievedRecipient.requireUuid()) + assertEquals(ACI_A, retrievedRecipient.requireAci()) assertEquals(E164_A, retrievedRecipient.requireE164()) val existingE164Recipient = Recipient.resolved(recipientIdE164) @@ -211,8 +212,8 @@ class RecipientDatabaseTest_merges { ) companion object { - val ACI_A = UUID.fromString("3436efbe-5a76-47fa-a98a-7e72c948a82e") - val ACI_B = UUID.fromString("8de7f691-0b60-4a68-9cd9-ed2f8453f9ed") + val ACI_A = ACI.from(UUID.fromString("3436efbe-5a76-47fa-a98a-7e72c948a82e")) + val ACI_B = ACI.from(UUID.fromString("8de7f691-0b60-4a68-9cd9-ed2f8453f9ed")) val E164_A = "+12221234567" val E164_B = "+13331234567" diff --git a/app/src/main/java/org/thoughtcrime/securesms/ContactSelectionListFragment.java b/app/src/main/java/org/thoughtcrime/securesms/ContactSelectionListFragment.java index 265d501e16..0ababe0e58 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/ContactSelectionListFragment.java +++ b/app/src/main/java/org/thoughtcrime/securesms/ContactSelectionListFragment.java @@ -26,7 +26,6 @@ import android.database.Cursor; import android.os.AsyncTask; import android.os.Bundle; import android.text.TextUtils; -import android.util.AttributeSet; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; @@ -572,7 +571,7 @@ public final class ContactSelectionListFragment extends LoggingFragment AlertDialog loadingDialog = SimpleProgressDialog.show(requireContext()); SimpleTask.run(getViewLifecycleOwner().getLifecycle(), () -> { - return UsernameUtil.fetchUuidForUsername(requireContext(), contact.getNumber()); + return UsernameUtil.fetchAciForUsername(requireContext(), contact.getNumber()); }, uuid -> { loadingDialog.dismiss(); if (uuid.isPresent()) { diff --git a/app/src/main/java/org/thoughtcrime/securesms/NewConversationActivity.java b/app/src/main/java/org/thoughtcrime/securesms/NewConversationActivity.java index eeb0859cc4..7fe55aabb8 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/NewConversationActivity.java +++ b/app/src/main/java/org/thoughtcrime/securesms/NewConversationActivity.java @@ -75,7 +75,7 @@ public class NewConversationActivity extends ContactSelectionActivity SimpleTask.run(getLifecycle(), () -> { Recipient resolved = Recipient.external(this, number); - if (!resolved.isRegistered() || !resolved.hasUuid()) { + if (!resolved.isRegistered() || !resolved.hasAci()) { Log.i(TAG, "[onContactSelected] Not registered or no UUID. Doing a directory refresh."); try { DirectoryHelper.refreshDirectoryFor(this, resolved, false); diff --git a/app/src/main/java/org/thoughtcrime/securesms/VerifyIdentityActivity.java b/app/src/main/java/org/thoughtcrime/securesms/VerifyIdentityActivity.java index 40370310a6..436867123f 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/VerifyIdentityActivity.java +++ b/app/src/main/java/org/thoughtcrime/securesms/VerifyIdentityActivity.java @@ -56,7 +56,6 @@ import android.widget.Toast; import androidx.annotation.DrawableRes; import androidx.annotation.NonNull; -import androidx.appcompat.app.AlertDialog; import androidx.appcompat.app.AppCompatActivity; import androidx.appcompat.widget.Toolbar; import androidx.core.view.OneShotPreDrawListener; @@ -64,6 +63,8 @@ import androidx.fragment.app.Fragment; import androidx.fragment.app.FragmentTransaction; import androidx.interpolator.view.animation.FastOutSlowInInterpolator; +import com.google.android.material.dialog.MaterialAlertDialogBuilder; + import org.signal.core.util.ThreadUtil; import org.signal.core.util.concurrent.SignalExecutors; import org.signal.core.util.logging.Log; @@ -322,23 +323,26 @@ public class VerifyIdentityActivity extends PassphraseRequiredActivity implement //noinspection WrongThread Recipient resolved = recipient.resolve(); - if (FeatureFlags.verifyV2() && resolved.getUuid().isPresent()) { + if (FeatureFlags.verifyV2() && resolved.getAci().isPresent()) { Log.i(TAG, "Using UUID (version 2)."); version = 2; - localId = UuidUtil.toByteArray(TextSecurePreferences.getLocalUuid(requireContext())); - remoteId = UuidUtil.toByteArray(resolved.getUuid().get()); + localId = TextSecurePreferences.getLocalAci(requireContext()).toByteArray(); + remoteId = resolved.requireAci().toByteArray(); } else if (!FeatureFlags.verifyV2() && resolved.getE164().isPresent()) { Log.i(TAG, "Using E164 (version 1)."); version = 1; localId = TextSecurePreferences.getLocalNumber(requireContext()).getBytes(); remoteId = resolved.requireE164().getBytes(); } else { - Log.w(TAG, String.format(Locale.ENGLISH, "Could not show proper verification! verifyV2: %s, hasUuid: %s, hasE164: %s", FeatureFlags.verifyV2(), resolved.getUuid().isPresent(), resolved.getE164().isPresent())); - new AlertDialog.Builder(requireContext()) - .setMessage(getString(R.string.VerifyIdentityActivity_you_must_first_exchange_messages_in_order_to_view, resolved.getDisplayName(requireContext()))) - .setPositiveButton(android.R.string.ok, (dialog, which) -> requireActivity().finish()) - .setOnDismissListener(dialog -> requireActivity().finish()) - .show(); + Log.w(TAG, String.format(Locale.ENGLISH, "Could not show proper verification! verifyV2: %s, hasUuid: %s, hasE164: %s", FeatureFlags.verifyV2(), resolved.getAci().isPresent(), resolved.getE164().isPresent())); + new MaterialAlertDialogBuilder(requireContext()) + .setMessage(getString(R.string.VerifyIdentityActivity_you_must_first_exchange_messages_in_order_to_view, resolved.getDisplayName(requireContext()))) + .setPositiveButton(android.R.string.ok, (dialog, which) -> requireActivity().finish()) + .setOnDismissListener(dialog -> { + requireActivity().finish(); + dialog.dismiss(); + }) + .show(); return; } diff --git a/app/src/main/java/org/thoughtcrime/securesms/components/settings/conversation/InternalConversationSettingsFragment.kt b/app/src/main/java/org/thoughtcrime/securesms/components/settings/conversation/InternalConversationSettingsFragment.kt index e2d6b590c9..4763402bd0 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/components/settings/conversation/InternalConversationSettingsFragment.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/components/settings/conversation/InternalConversationSettingsFragment.kt @@ -26,8 +26,8 @@ import org.thoughtcrime.securesms.util.Hex import org.thoughtcrime.securesms.util.SpanUtil import org.thoughtcrime.securesms.util.Util import org.thoughtcrime.securesms.util.livedata.Store +import org.whispersystems.signalservice.api.push.ACI import java.util.Objects -import java.util.UUID /** * Shows internal details about a recipient that you can view from the conversation settings. @@ -60,7 +60,7 @@ class InternalConversationSettingsFragment : DSLSettingsFragment( ) if (!recipient.isGroup) { - val uuid = recipient.uuid.transform(UUID::toString).or("null") + val uuid = recipient.aci.transform(ACI::toString).or("null") longClickPref( title = DSLSettingsText.from("UUID"), summary = DSLSettingsText.from(uuid), @@ -145,8 +145,8 @@ class InternalConversationSettingsFragment : DSLSettingsFragment( .setTitle("Are you sure?") .setNegativeButton(android.R.string.cancel) { d, _ -> d.dismiss() } .setPositiveButton(android.R.string.ok) { _, _ -> - if (recipient.hasUuid()) { - DatabaseFactory.getSessionDatabase(context).deleteAllFor(recipient.requireUuid().toString()) + if (recipient.hasAci()) { + DatabaseFactory.getSessionDatabase(context).deleteAllFor(recipient.requireAci().toString()) } if (recipient.hasE164()) { DatabaseFactory.getSessionDatabase(context).deleteAllFor(recipient.requireE164()) diff --git a/app/src/main/java/org/thoughtcrime/securesms/components/webrtc/CallParticipantsState.kt b/app/src/main/java/org/thoughtcrime/securesms/components/webrtc/CallParticipantsState.kt index 43bf7d3c28..40e2b74a86 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/components/webrtc/CallParticipantsState.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/components/webrtc/CallParticipantsState.kt @@ -127,10 +127,10 @@ data class CallParticipantsState( fun getIncomingRingingGroupDescription(context: Context): String? { if (callState == WebRtcViewModel.State.CALL_INCOMING && groupCallState == WebRtcViewModel.GroupCallState.RINGING && - ringerRecipient.hasUuid() + ringerRecipient.hasAci() ) { val ringerName = ringerRecipient.getShortDisplayName(context) - val membersWithoutYouOrRinger: List = groupMembers.filterNot { it.member.isSelf || ringerRecipient.requireUuid() == it.member.uuid.orNull() } + val membersWithoutYouOrRinger: List = groupMembers.filterNot { it.member.isSelf || ringerRecipient.requireAci() == it.member.aci.orNull() } return when (membersWithoutYouOrRinger.size) { 0 -> context.getString(R.string.WebRtcCallView__s_is_calling_you, ringerName) diff --git a/app/src/main/java/org/thoughtcrime/securesms/contacts/sync/ContactDiscoveryV2.java b/app/src/main/java/org/thoughtcrime/securesms/contacts/sync/ContactDiscoveryV2.java index c611ad6a12..265f90c8d9 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/contacts/sync/ContactDiscoveryV2.java +++ b/app/src/main/java/org/thoughtcrime/securesms/contacts/sync/ContactDiscoveryV2.java @@ -16,6 +16,7 @@ import org.thoughtcrime.securesms.push.IasTrustStore; import org.thoughtcrime.securesms.util.SetUtil; import org.whispersystems.libsignal.InvalidKeyException; import org.whispersystems.signalservice.api.SignalServiceAccountManager; +import org.whispersystems.signalservice.api.push.ACI; import org.whispersystems.signalservice.api.push.TrustStore; import org.whispersystems.signalservice.internal.contacts.crypto.Quote; import org.whispersystems.signalservice.internal.contacts.crypto.UnauthenticatedQuoteException; @@ -66,7 +67,7 @@ class ContactDiscoveryV2 { KeyStore iasKeyStore = getIasKeyStore(context); try { - Map results = accountManager.getRegisteredUsers(iasKeyStore, sanitizedNumbers, BuildConfig.CDS_MRENCLAVE); + Map results = accountManager.getRegisteredUsers(iasKeyStore, sanitizedNumbers, BuildConfig.CDS_MRENCLAVE); FuzzyPhoneNumberHelper.OutputResult outputResult = FuzzyPhoneNumberHelper.generateOutput(results, inputResult); return new DirectoryResult(outputResult.getNumbers(), outputResult.getRewrites(), ignoredNumbers); diff --git a/app/src/main/java/org/thoughtcrime/securesms/contacts/sync/ContactDiscoveryV3.java b/app/src/main/java/org/thoughtcrime/securesms/contacts/sync/ContactDiscoveryV3.java index 9028c70315..acfe806ede 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/contacts/sync/ContactDiscoveryV3.java +++ b/app/src/main/java/org/thoughtcrime/securesms/contacts/sync/ContactDiscoveryV3.java @@ -9,6 +9,7 @@ import org.thoughtcrime.securesms.contacts.sync.DirectoryHelper.DirectoryResult; import org.thoughtcrime.securesms.dependencies.ApplicationDependencies; import org.thoughtcrime.securesms.util.SetUtil; import org.whispersystems.signalservice.api.SignalServiceAccountManager; +import org.whispersystems.signalservice.api.push.ACI; import java.io.IOException; import java.util.ArrayList; @@ -46,7 +47,7 @@ class ContactDiscoveryV3 { SignalServiceAccountManager accountManager = ApplicationDependencies.getSignalServiceAccountManager(); try { - Map results = accountManager.getRegisteredUsersWithCdsh(sanitizedNumbers, BuildConfig.CDSH_PUBLIC_KEY, BuildConfig.CDSH_CODE_HASH); + Map results = accountManager.getRegisteredUsersWithCdsh(sanitizedNumbers, BuildConfig.CDSH_PUBLIC_KEY, BuildConfig.CDSH_CODE_HASH); FuzzyPhoneNumberHelper.OutputResult outputResult = FuzzyPhoneNumberHelper.generateOutput(results, inputResult); return new DirectoryResult(outputResult.getNumbers(), outputResult.getRewrites(), ignoredNumbers); diff --git a/app/src/main/java/org/thoughtcrime/securesms/contacts/sync/DirectoryHelper.java b/app/src/main/java/org/thoughtcrime/securesms/contacts/sync/DirectoryHelper.java index 0901fc00ef..ae2ad62270 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/contacts/sync/DirectoryHelper.java +++ b/app/src/main/java/org/thoughtcrime/securesms/contacts/sync/DirectoryHelper.java @@ -29,6 +29,7 @@ import org.thoughtcrime.securesms.database.MessageDatabase.InsertResult; import org.thoughtcrime.securesms.database.RecipientDatabase; import org.thoughtcrime.securesms.database.RecipientDatabase.BulkOperationsHandle; import org.thoughtcrime.securesms.database.RecipientDatabase.RegisteredState; +import org.whispersystems.signalservice.api.push.ACI; import org.thoughtcrime.securesms.dependencies.ApplicationDependencies; import org.thoughtcrime.securesms.jobs.MultiDeviceContactUpdateJob; import org.thoughtcrime.securesms.jobs.RetrieveProfileJob; @@ -67,7 +68,6 @@ import java.util.List; import java.util.Map; import java.util.Objects; import java.util.Set; -import java.util.UUID; import java.util.concurrent.TimeUnit; import io.reactivex.rxjava3.core.Observable; @@ -112,9 +112,9 @@ public class DirectoryHelper { RecipientDatabase recipientDatabase = DatabaseFactory.getRecipientDatabase(context); for (Recipient recipient : recipients) { - if (recipient.hasUuid() && !recipient.hasE164()) { - if (isUuidRegistered(context, recipient)) { - recipientDatabase.markRegistered(recipient.getId(), recipient.requireUuid()); + if (recipient.hasAci() && !recipient.hasE164()) { + if (isAciRegistered(context, recipient)) { + recipientDatabase.markRegistered(recipient.getId(), recipient.requireAci()); } else { recipientDatabase.markUnregistered(recipient.getId()); } @@ -136,11 +136,11 @@ public class DirectoryHelper { RegisteredState originalRegisteredState = recipient.resolve().getRegistered(); RegisteredState newRegisteredState; - if (recipient.hasUuid() && !recipient.hasE164()) { - boolean isRegistered = isUuidRegistered(context, recipient); + if (recipient.hasAci() && !recipient.hasE164()) { + boolean isRegistered = isAciRegistered(context, recipient); stopwatch.split("uuid-network"); if (isRegistered) { - boolean idChanged = recipientDatabase.markRegistered(recipient.getId(), recipient.getUuid().get()); + boolean idChanged = recipientDatabase.markRegistered(recipient.getId(), recipient.requireAci()); if (idChanged) { Log.w(TAG, "ID changed during refresh by UUID."); } @@ -169,18 +169,18 @@ public class DirectoryHelper { } if (result.getRegisteredNumbers().size() > 0) { - UUID uuid = result.getRegisteredNumbers().values().iterator().next(); - if (uuid != null) { - boolean idChanged = recipientDatabase.markRegistered(recipient.getId(), uuid); + ACI aci = result.getRegisteredNumbers().values().iterator().next(); + if (aci != null) { + boolean idChanged = recipientDatabase.markRegistered(recipient.getId(), aci); if (idChanged) { - recipient = Recipient.resolved(recipientDatabase.getByUuid(uuid).get()); + recipient = Recipient.resolved(recipientDatabase.getByAci(aci).get()); } } else { Log.w(TAG, "Registered number set had a null UUID!"); } - } else if (recipient.hasUuid() && recipient.isRegistered() && hasCommunicatedWith(context, recipient)) { - if (isUuidRegistered(context, recipient)) { - recipientDatabase.markRegistered(recipient.getId(), recipient.requireUuid()); + } else if (recipient.hasAci() && recipient.isRegistered() && hasCommunicatedWith(context, recipient)) { + if (isAciRegistered(context, recipient)) { + recipientDatabase.markRegistered(recipient.getId(), recipient.requireAci()); } else { recipientDatabase.markUnregistered(recipient.getId()); } @@ -245,10 +245,10 @@ public class DirectoryHelper { recipientDatabase.updatePhoneNumbers(result.getNumberRewrites()); } - Map uuidMap = recipientDatabase.bulkProcessCdsResult(result.getRegisteredNumbers()); - Set activeNumbers = result.getRegisteredNumbers().keySet(); - Set activeIds = uuidMap.keySet(); - Set inactiveIds = Stream.of(allNumbers) + Map aciMap = recipientDatabase.bulkProcessCdsResult(result.getRegisteredNumbers()); + Set activeNumbers = result.getRegisteredNumbers().keySet(); + Set activeIds = aciMap.keySet(); + Set inactiveIds = Stream.of(allNumbers) .filterNot(activeNumbers::contains) .filterNot(n -> result.getNumberRewrites().containsKey(n)) .filterNot(n -> result.getIgnoredNumbers().contains(n)) @@ -270,7 +270,7 @@ public class DirectoryHelper { Set preExistingRegisteredUsers = new HashSet<>(recipientDatabase.getRegistered()); - recipientDatabase.bulkUpdatedRegisteredStatus(uuidMap, inactiveIds); + recipientDatabase.bulkUpdatedRegisteredStatus(aciMap, inactiveIds); stopwatch.split("update-registered"); @@ -298,7 +298,7 @@ public class DirectoryHelper { } - private static boolean isUuidRegistered(@NonNull Context context, @NonNull Recipient recipient) throws IOException { + private static boolean isAciRegistered(@NonNull Context context, @NonNull Recipient recipient) throws IOException { try { ProfileUtil.retrieveProfileSync(context, recipient, SignalServiceProfile.RequestType.PROFILE); return true; @@ -514,7 +514,7 @@ public class DirectoryHelper { List possiblyUnlisted = Stream.of(inactiveIds) .map(Recipient::resolved) .filter(Recipient::isRegistered) - .filter(Recipient::hasUuid) + .filter(Recipient::hasAci) .filter(r -> hasCommunicatedWith(context, r)) .toList(); @@ -549,17 +549,17 @@ public class DirectoryHelper { } private static boolean hasCommunicatedWith(@NonNull Context context, @NonNull Recipient recipient) { - return DatabaseFactory.getThreadDatabase(context).hasThread(recipient.getId()) || - (recipient.hasUuid() && DatabaseFactory.getSessionDatabase(context).hasSessionFor(recipient.requireUuid().toString())) || + return DatabaseFactory.getThreadDatabase(context).hasThread(recipient.getId()) || + (recipient.hasAci() && DatabaseFactory.getSessionDatabase(context).hasSessionFor(recipient.requireAci().toString())) || (recipient.hasE164() && DatabaseFactory.getSessionDatabase(context).hasSessionFor(recipient.requireE164())); } static class DirectoryResult { - private final Map registeredNumbers; + private final Map registeredNumbers; private final Map numberRewrites; private final Set ignoredNumbers; - DirectoryResult(@NonNull Map registeredNumbers, + DirectoryResult(@NonNull Map registeredNumbers, @NonNull Map numberRewrites, @NonNull Set ignoredNumbers) { @@ -569,7 +569,7 @@ public class DirectoryHelper { } - @NonNull Map getRegisteredNumbers() { + @NonNull Map getRegisteredNumbers() { return registeredNumbers; } diff --git a/app/src/main/java/org/thoughtcrime/securesms/contacts/sync/FuzzyPhoneNumberHelper.java b/app/src/main/java/org/thoughtcrime/securesms/contacts/sync/FuzzyPhoneNumberHelper.java index d1432202f4..66ab81f69f 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/contacts/sync/FuzzyPhoneNumberHelper.java +++ b/app/src/main/java/org/thoughtcrime/securesms/contacts/sync/FuzzyPhoneNumberHelper.java @@ -4,6 +4,8 @@ import androidx.annotation.NonNull; import androidx.annotation.Nullable; import androidx.annotation.VisibleForTesting; +import org.whispersystems.signalservice.api.push.ACI; + import java.util.Arrays; import java.util.Collection; import java.util.HashMap; @@ -50,8 +52,8 @@ class FuzzyPhoneNumberHelper { * these results and our initial input set, we can decide if we need to rewrite which number we * have stored locally. */ - static @NonNull OutputResult generateOutput(@NonNull Map registeredNumbers, @NonNull InputResult inputResult) { - Map allNumbers = new HashMap<>(registeredNumbers); + static @NonNull OutputResult generateOutput(@NonNull Map registeredNumbers, @NonNull InputResult inputResult) { + Map allNumbers = new HashMap<>(registeredNumbers); Map rewrites = new HashMap<>(); for (Map.Entry entry : inputResult.getMapOfOriginalToVariant().entrySet()) { @@ -170,15 +172,15 @@ class FuzzyPhoneNumberHelper { } public static class OutputResult { - private final Map numbers; + private final Map numbers; private final Map rewrites; - private OutputResult(@NonNull Map numbers, @NonNull Map rewrites) { + private OutputResult(@NonNull Map numbers, @NonNull Map rewrites) { this.numbers = numbers; this.rewrites = rewrites; } - public @NonNull Map getNumbers() { + public @NonNull Map getNumbers() { return numbers; } diff --git a/app/src/main/java/org/thoughtcrime/securesms/conversation/ConversationActivity.java b/app/src/main/java/org/thoughtcrime/securesms/conversation/ConversationActivity.java index 40c05789a0..40741fbee4 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/conversation/ConversationActivity.java +++ b/app/src/main/java/org/thoughtcrime/securesms/conversation/ConversationActivity.java @@ -249,7 +249,6 @@ import org.thoughtcrime.securesms.search.MessageResult; import org.thoughtcrime.securesms.service.KeyCachingService; import org.thoughtcrime.securesms.sms.MessageSender; import org.thoughtcrime.securesms.sms.OutgoingEncryptedMessage; -import org.thoughtcrime.securesms.sms.OutgoingEndSessionMessage; import org.thoughtcrime.securesms.sms.OutgoingTextMessage; import org.thoughtcrime.securesms.stickers.StickerEventListener; import org.thoughtcrime.securesms.stickers.StickerLocator; @@ -1521,7 +1520,7 @@ public class ConversationActivity extends PassphraseRequiredActivity sendButton.resetAvailableTransports(isMediaMessage); - if (!isSecureText && !isPushGroupConversation() && !recipient.get().isUuidOnly()) { + if (!isSecureText && !isPushGroupConversation() && !recipient.get().isAciOnly()) { sendButton.disableTransport(Type.TEXTSECURE); } @@ -1532,7 +1531,7 @@ public class ConversationActivity extends PassphraseRequiredActivity if (!recipient.get().isPushGroup() && recipient.get().isForceSmsSelection()) { sendButton.setDefaultTransport(Type.SMS); } else { - if (isSecureText || isPushGroupConversation() || recipient.get().isUuidOnly()) { + if (isSecureText || isPushGroupConversation() || recipient.get().isAciOnly()) { sendButton.setDefaultTransport(Type.TEXTSECURE); } else { sendButton.setDefaultTransport(Type.SMS); @@ -2942,7 +2941,7 @@ public class ConversationActivity extends PassphraseRequiredActivity return new SettableFuture<>(null); } - final boolean sendPush = (isSecureText && !forceSms) || recipient.get().isUuidOnly(); + final boolean sendPush = (isSecureText && !forceSms) || recipient.get().isAciOnly(); final long thread = this.threadId; if (sendPush) { @@ -3005,7 +3004,7 @@ public class ConversationActivity extends PassphraseRequiredActivity final long thread = this.threadId; final Context context = getApplicationContext(); final String messageBody = getMessage(); - final boolean sendPush = (isSecureText && !forceSms) || recipient.get().isUuidOnly(); + final boolean sendPush = (isSecureText && !forceSms) || recipient.get().isAciOnly(); OutgoingTextMessage message; diff --git a/app/src/main/java/org/thoughtcrime/securesms/conversation/ConversationUpdateItem.java b/app/src/main/java/org/thoughtcrime/securesms/conversation/ConversationUpdateItem.java index 69a0c2d257..9db544a6c9 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/conversation/ConversationUpdateItem.java +++ b/app/src/main/java/org/thoughtcrime/securesms/conversation/ConversationUpdateItem.java @@ -47,10 +47,9 @@ import org.thoughtcrime.securesms.util.ViewUtil; import org.thoughtcrime.securesms.util.concurrent.ListenableFuture; import org.thoughtcrime.securesms.util.livedata.LiveDataUtil; import org.whispersystems.libsignal.util.guava.Optional; +import org.whispersystems.signalservice.api.push.ACI; import java.util.Collection; -import java.util.Collections; -import java.util.List; import java.util.Locale; import java.util.Objects; import java.util.Set; @@ -343,11 +342,11 @@ public final class ConversationUpdateItem extends FrameLayout }); } else if (conversationMessage.getMessageRecord().isGroupCall()) { UpdateDescription updateDescription = MessageRecord.getGroupCallUpdateDescription(getContext(), conversationMessage.getMessageRecord().getBody(), true); - Collection uuids = updateDescription.getMentioned(); + Collection acis = updateDescription.getMentioned(); int text = 0; - if (Util.hasItems(uuids)) { - if (uuids.contains(TextSecurePreferences.getLocalUuid(getContext()))) { + if (Util.hasItems(acis)) { + if (acis.contains(TextSecurePreferences.getLocalAci(getContext()))) { text = R.string.ConversationUpdateItem_return_to_call; } else if (GroupCallUpdateDetailsUtil.parse(conversationMessage.getMessageRecord().getBody()).getIsCallFull()) { text = R.string.ConversationUpdateItem_call_is_full; diff --git a/app/src/main/java/org/thoughtcrime/securesms/crypto/storage/TextSecureIdentityKeyStore.java b/app/src/main/java/org/thoughtcrime/securesms/crypto/storage/TextSecureIdentityKeyStore.java index eb0dc3260b..0892c11cd5 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/crypto/storage/TextSecureIdentityKeyStore.java +++ b/app/src/main/java/org/thoughtcrime/securesms/crypto/storage/TextSecureIdentityKeyStore.java @@ -5,8 +5,6 @@ import android.content.Context; import androidx.annotation.NonNull; import androidx.annotation.Nullable; -import com.google.android.exoplayer2.C; - import org.signal.core.util.logging.Log; import org.thoughtcrime.securesms.crypto.IdentityKeyUtil; import org.thoughtcrime.securesms.crypto.SessionUtil; @@ -124,7 +122,7 @@ public class TextSecureIdentityKeyStore implements IdentityKeyStore { @Override public boolean isTrustedIdentity(SignalProtocolAddress address, IdentityKey identityKey, Direction direction) { - boolean isSelf = address.getName().equals(TextSecurePreferences.getLocalUuid(context).toString()) || + boolean isSelf = address.getName().equals(TextSecurePreferences.getLocalAci(context).toString()) || address.getName().equals(TextSecurePreferences.getLocalNumber(context)); if (isSelf) { diff --git a/app/src/main/java/org/thoughtcrime/securesms/crypto/storage/TextSecureSessionStore.java b/app/src/main/java/org/thoughtcrime/securesms/crypto/storage/TextSecureSessionStore.java index eeed379899..2c265513d5 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/crypto/storage/TextSecureSessionStore.java +++ b/app/src/main/java/org/thoughtcrime/securesms/crypto/storage/TextSecureSessionStore.java @@ -134,8 +134,8 @@ public class TextSecureSessionStore implements SignalServiceSessionStore { synchronized (LOCK) { Recipient recipient = Recipient.resolved(recipientId); - if (recipient.hasUuid()) { - archiveSession(new SignalProtocolAddress(recipient.requireUuid().toString(), deviceId)); + if (recipient.hasAci()) { + archiveSession(new SignalProtocolAddress(recipient.requireAci().toString(), deviceId)); } if (recipient.hasE164()) { diff --git a/app/src/main/java/org/thoughtcrime/securesms/database/GroupDatabase.java b/app/src/main/java/org/thoughtcrime/securesms/database/GroupDatabase.java index d54aabd585..a8f06b8261 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/database/GroupDatabase.java +++ b/app/src/main/java/org/thoughtcrime/securesms/database/GroupDatabase.java @@ -26,6 +26,7 @@ import org.thoughtcrime.securesms.database.helpers.SQLCipherOpenHelper; import org.thoughtcrime.securesms.dependencies.ApplicationDependencies; import org.thoughtcrime.securesms.groups.v2.processing.GroupsV2StateProcessor; import org.thoughtcrime.securesms.jobs.RequestGroupV2InfoJob; +import org.whispersystems.signalservice.api.push.ACI; import org.whispersystems.signalservice.api.push.DistributionId; import org.thoughtcrime.securesms.groups.GroupAccessControl; import org.thoughtcrime.securesms.groups.GroupId; @@ -804,10 +805,10 @@ private static final String[] GROUP_PROJECTION = { } private static boolean gv2GroupActive(@NonNull DecryptedGroup decryptedGroup) { - UUID uuid = Recipient.self().getUuid().get(); + ACI aci = Recipient.self().requireAci(); - return DecryptedGroupUtil.findMemberByUuid(decryptedGroup.getMembersList(), uuid).isPresent() || - DecryptedGroupUtil.findPendingByUuid(decryptedGroup.getPendingMembersList(), uuid).isPresent(); + return DecryptedGroupUtil.findMemberByUuid(decryptedGroup.getMembersList(), aci.uuid()).isPresent() || + DecryptedGroupUtil.findPendingByUuid(decryptedGroup.getPendingMembersList(), aci.uuid()).isPresent(); } private List getCurrentMembers(@NonNull GroupId groupId) { @@ -868,7 +869,7 @@ private static final String[] GROUP_PROJECTION = { if (UuidUtil.UNKNOWN_UUID.equals(uuid)) { Log.w(TAG, "Seen unknown UUID in members list"); } else { - groupMembers.add(RecipientId.from(uuid, null)); + groupMembers.add(RecipientId.from(ACI.from(uuid), null)); } } @@ -1186,9 +1187,9 @@ private static final String[] GROUP_PROJECTION = { */ public boolean isPendingMember(@NonNull Recipient recipient) { if (isV2Group()) { - Optional uuid = recipient.getUuid(); - if (uuid.isPresent()) { - return DecryptedGroupUtil.findPendingByUuid(requireV2GroupProperties().getDecryptedGroup().getPendingMembersList(), uuid.get()) + Optional aci = recipient.getAci(); + if (aci.isPresent()) { + return DecryptedGroupUtil.findPendingByUuid(requireV2GroupProperties().getDecryptedGroup().getPendingMembersList(), aci.get().uuid()) .isPresent(); } } @@ -1229,13 +1230,13 @@ private static final String[] GROUP_PROJECTION = { } public boolean isAdmin(@NonNull Recipient recipient) { - Optional uuid = recipient.getUuid(); + Optional aci = recipient.getAci(); - if (!uuid.isPresent()) { + if (!aci.isPresent()) { return false; } - return DecryptedGroupUtil.findMemberByUuid(getDecryptedGroup().getMembersList(), uuid.get()) + return DecryptedGroupUtil.findMemberByUuid(getDecryptedGroup().getMembersList(), aci.get().uuid()) .transform(t -> t.getRole() == Member.Role.ADMINISTRATOR) .or(false); } @@ -1245,21 +1246,21 @@ private static final String[] GROUP_PROJECTION = { } public MemberLevel memberLevel(@NonNull Recipient recipient) { - Optional uuid = recipient.getUuid(); + Optional aci = recipient.getAci(); - if (!uuid.isPresent()) { + if (!aci.isPresent()) { return MemberLevel.NOT_A_MEMBER; } DecryptedGroup decryptedGroup = getDecryptedGroup(); - return DecryptedGroupUtil.findMemberByUuid(decryptedGroup.getMembersList(), uuid.get()) + return DecryptedGroupUtil.findMemberByUuid(decryptedGroup.getMembersList(), aci.get().uuid()) .transform(member -> member.getRole() == Member.Role.ADMINISTRATOR ? MemberLevel.ADMINISTRATOR : MemberLevel.FULL_MEMBER) - .or(() -> DecryptedGroupUtil.findPendingByUuid(decryptedGroup.getPendingMembersList(), uuid.get()) + .or(() -> DecryptedGroupUtil.findPendingByUuid(decryptedGroup.getPendingMembersList(), aci.get().uuid()) .transform(m -> MemberLevel.PENDING_MEMBER) - .or(() -> DecryptedGroupUtil.findRequestingByUuid(decryptedGroup.getRequestingMembersList(), uuid.get()) + .or(() -> DecryptedGroupUtil.findRequestingByUuid(decryptedGroup.getRequestingMembersList(), aci.get().uuid()) .transform(m -> MemberLevel.REQUESTING_MEMBER) .or(MemberLevel.NOT_A_MEMBER))); } @@ -1271,7 +1272,7 @@ private static final String[] GROUP_PROJECTION = { public List getMemberRecipientIds(@NonNull MemberSet memberSet) { boolean includeSelf = memberSet.includeSelf; DecryptedGroup groupV2 = getDecryptedGroup(); - UUID selfUuid = Recipient.self().getUuid().get(); + UUID selfUuid = Recipient.self().requireAci().uuid(); List recipients = new ArrayList<>(groupV2.getMembersCount() + groupV2.getPendingMembersCount()); int unknownMembers = 0; int unknownPending = 0; @@ -1280,7 +1281,7 @@ private static final String[] GROUP_PROJECTION = { if (UuidUtil.UNKNOWN_UUID.equals(uuid)) { unknownMembers++; } else if (includeSelf || !selfUuid.equals(uuid)) { - recipients.add(RecipientId.from(uuid, null)); + recipients.add(RecipientId.from(ACI.from(uuid), null)); } } if (memberSet.includePending) { @@ -1288,7 +1289,7 @@ private static final String[] GROUP_PROJECTION = { if (UuidUtil.UNKNOWN_UUID.equals(uuid)) { unknownPending++; } else if (includeSelf || !selfUuid.equals(uuid)) { - recipients.add(RecipientId.from(uuid, null)); + recipients.add(RecipientId.from(ACI.from(uuid), null)); } } } diff --git a/app/src/main/java/org/thoughtcrime/securesms/database/MentionUtil.java b/app/src/main/java/org/thoughtcrime/securesms/database/MentionUtil.java index ed1799f5d0..6af572dced 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/database/MentionUtil.java +++ b/app/src/main/java/org/thoughtcrime/securesms/database/MentionUtil.java @@ -18,6 +18,7 @@ import org.thoughtcrime.securesms.database.model.MessageRecord; import org.thoughtcrime.securesms.database.model.databaseprotos.BodyRangeList; import org.thoughtcrime.securesms.recipients.Recipient; import org.thoughtcrime.securesms.recipients.RecipientId; +import org.whispersystems.signalservice.api.push.ACI; import org.whispersystems.signalservice.api.util.UuidUtil; import java.util.ArrayList; @@ -105,7 +106,7 @@ public final class MentionUtil { BodyRangeList.Builder builder = BodyRangeList.newBuilder(); for (Mention mention : mentions) { - String uuid = Recipient.resolved(mention.getRecipientId()).requireUuid().toString(); + String uuid = Recipient.resolved(mention.getRecipientId()).requireAci().toString(); builder.addRanges(BodyRangeList.BodyRange.newBuilder() .setMentionUuid(uuid) .setStart(mention.getStart()) @@ -121,7 +122,7 @@ public final class MentionUtil { return Stream.of(BodyRangeList.parseFrom(data).getRangesList()) .filter(bodyRange -> bodyRange.getAssociatedValueCase() == BodyRangeList.BodyRange.AssociatedValueCase.MENTIONUUID) .map(mention -> { - RecipientId id = Recipient.externalPush(context, UuidUtil.parseOrThrow(mention.getMentionUuid()), null, false).getId(); + RecipientId id = Recipient.externalPush(context, ACI.parseOrThrow(mention.getMentionUuid()), null, false).getId(); return new Mention(id, mention.getStart(), mention.getLength()); }) .toList(); diff --git a/app/src/main/java/org/thoughtcrime/securesms/database/MmsDatabase.java b/app/src/main/java/org/thoughtcrime/securesms/database/MmsDatabase.java index 1aa32aeeaa..5835cc4000 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/database/MmsDatabase.java +++ b/app/src/main/java/org/thoughtcrime/securesms/database/MmsDatabase.java @@ -81,6 +81,7 @@ import org.thoughtcrime.securesms.util.TextSecurePreferences; import org.thoughtcrime.securesms.util.Util; import org.whispersystems.libsignal.util.Pair; import org.whispersystems.libsignal.util.guava.Optional; +import org.whispersystems.signalservice.api.push.ACI; import java.io.IOException; import java.security.SecureRandom; @@ -1559,7 +1560,7 @@ public class MmsDatabase extends MessageDatabase { MessageGroupContext.GroupV2Properties groupV2Properties = outgoingGroupUpdateMessage.requireGroupV2Properties(); members.addAll(Stream.of(groupV2Properties.getAllActivePendingAndRemovedMembers()) .distinct() - .map(uuid -> RecipientId.from(uuid, null)) + .map(uuid -> RecipientId.from(ACI.from(uuid), null)) .toList()); members.remove(Recipient.self().getId()); } else { diff --git a/app/src/main/java/org/thoughtcrime/securesms/database/RecipientDatabase.java b/app/src/main/java/org/thoughtcrime/securesms/database/RecipientDatabase.java index 61cbf922a3..d0f4b5d3a5 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/database/RecipientDatabase.java +++ b/app/src/main/java/org/thoughtcrime/securesms/database/RecipientDatabase.java @@ -33,6 +33,7 @@ import org.thoughtcrime.securesms.crypto.ProfileKeyUtil; import org.thoughtcrime.securesms.crypto.storage.TextSecureIdentityKeyStore; import org.thoughtcrime.securesms.database.IdentityDatabase.VerifiedStatus; import org.thoughtcrime.securesms.database.helpers.SQLCipherOpenHelper; +import org.whispersystems.signalservice.api.push.ACI; import org.thoughtcrime.securesms.database.model.IdentityRecord; import org.thoughtcrime.securesms.database.model.ThreadRecord; import org.thoughtcrime.securesms.database.model.databaseprotos.BadgeList; @@ -80,7 +81,6 @@ import org.whispersystems.signalservice.api.storage.SignalContactRecord; import org.whispersystems.signalservice.api.storage.SignalGroupV1Record; import org.whispersystems.signalservice.api.storage.SignalGroupV2Record; import org.whispersystems.signalservice.api.storage.StorageId; -import org.whispersystems.signalservice.api.util.UuidUtil; import java.io.Closeable; import java.io.IOException; @@ -107,7 +107,7 @@ public class RecipientDatabase extends Database { static final String TABLE_NAME = "recipient"; public static final String ID = "_id"; - private static final String UUID = "uuid"; + private static final String ACI_COLUMN = "uuid"; private static final String USERNAME = "username"; public static final String PHONE = "phone"; public static final String EMAIL = "email"; @@ -178,7 +178,7 @@ public class RecipientDatabase extends Database { } private static final String[] RECIPIENT_PROJECTION = new String[] { - ID, UUID, USERNAME, PHONE, EMAIL, GROUP_ID, GROUP_TYPE, + ID, ACI_COLUMN, USERNAME, PHONE, EMAIL, GROUP_ID, GROUP_TYPE, BLOCKED, MESSAGE_RINGTONE, CALL_RINGTONE, MESSAGE_VIBRATE, CALL_VIBRATE, MUTE_UNTIL, AVATAR_COLOR, SEEN_INVITE_REMINDER, DEFAULT_SUBSCRIPTION_ID, MESSAGE_EXPIRATION_TIME, REGISTERED, PROFILE_KEY, PROFILE_KEY_CREDENTIAL, SYSTEM_JOINED_NAME, SYSTEM_GIVEN_NAME, SYSTEM_FAMILY_NAME, SYSTEM_PHOTO_URI, SYSTEM_PHONE_LABEL, SYSTEM_PHONE_TYPE, SYSTEM_CONTACT_URI, @@ -329,7 +329,7 @@ public class RecipientDatabase extends Database { public static final String CREATE_TABLE = "CREATE TABLE " + TABLE_NAME + " (" + ID + " INTEGER PRIMARY KEY AUTOINCREMENT, " + - UUID + " TEXT UNIQUE DEFAULT NULL, " + + ACI_COLUMN + " TEXT UNIQUE DEFAULT NULL, " + USERNAME + " TEXT UNIQUE DEFAULT NULL, " + PHONE + " TEXT UNIQUE DEFAULT NULL, " + EMAIL + " TEXT UNIQUE DEFAULT NULL, " + @@ -398,7 +398,7 @@ public class RecipientDatabase extends Database { public @NonNull boolean containsPhoneOrUuid(@NonNull String id) { SQLiteDatabase db = databaseHelper.getSignalReadableDatabase(); - String query = UUID + " = ? OR " + PHONE + " = ?"; + String query = ACI_COLUMN + " = ? OR " + PHONE + " = ?"; String[] args = new String[]{id, id}; try (Cursor cursor = db.query(TABLE_NAME, new String[] { ID }, query, args, null, null, null)) { @@ -421,8 +421,8 @@ public class RecipientDatabase extends Database { } public @NonNull - Optional getByUuid(@NonNull UUID uuid) { - return getByColumn(UUID, uuid.toString()); + Optional getByAci(@NonNull ACI uuid) { + return getByColumn(ACI_COLUMN, uuid.toString()); } public @NonNull @@ -430,12 +430,12 @@ public class RecipientDatabase extends Database { return getByColumn(USERNAME, username); } - public @NonNull RecipientId getAndPossiblyMerge(@Nullable UUID uuid, @Nullable String e164, boolean highTrust) { - return getAndPossiblyMerge(uuid, e164, highTrust, false); + public @NonNull RecipientId getAndPossiblyMerge(@Nullable ACI aci, @Nullable String e164, boolean highTrust) { + return getAndPossiblyMerge(aci, e164, highTrust, false); } - public @NonNull RecipientId getAndPossiblyMerge(@Nullable UUID uuid, @Nullable String e164, boolean highTrust, boolean changeSelf) { - if (uuid == null && e164 == null) { + public @NonNull RecipientId getAndPossiblyMerge(@Nullable ACI aci, @Nullable String e164, boolean highTrust, boolean changeSelf) { + if (aci == null && e164 == null) { throw new IllegalArgumentException("Must provide a UUID or E164!"); } @@ -449,115 +449,115 @@ public class RecipientDatabase extends Database { try { Optional byE164 = e164 != null ? getByE164(e164) : Optional.absent(); - Optional byUuid = uuid != null ? getByUuid(uuid) : Optional.absent(); + Optional byAci = aci != null ? getByAci(aci) : Optional.absent(); RecipientId finalId; - if (!byE164.isPresent() && !byUuid.isPresent()) { + if (!byE164.isPresent() && !byAci.isPresent()) { Log.i(TAG, "Discovered a completely new user. Inserting.", true); if (highTrust) { - long id = db.insert(TABLE_NAME, null, buildContentValuesForNewUser(e164, uuid)); + long id = db.insert(TABLE_NAME, null, buildContentValuesForNewUser(e164, aci)); finalId = RecipientId.from(id); } else { - long id = db.insert(TABLE_NAME, null, buildContentValuesForNewUser(uuid == null ? e164 : null, uuid)); + long id = db.insert(TABLE_NAME, null, buildContentValuesForNewUser(aci == null ? e164 : null, aci)); finalId = RecipientId.from(id); } - } else if (byE164.isPresent() && !byUuid.isPresent()) { - if (uuid != null) { + } else if (byE164.isPresent() && !byAci.isPresent()) { + if (aci != null) { RecipientSettings e164Settings = getRecipientSettings(byE164.get()); - if (e164Settings.uuid != null) { + if (e164Settings.aci != null) { if (highTrust) { - Log.w(TAG, String.format(Locale.US, "Found out about a UUID (%s) for a known E164 user (%s), but that user already has a UUID (%s). Likely a case of re-registration. High-trust, so stripping the E164 from the existing account and assigning it to a new entry.", uuid, byE164.get(), e164Settings.uuid), true); + Log.w(TAG, String.format(Locale.US, "Found out about an ACI (%s) for a known E164 user (%s), but that user already has an ACI (%s). Likely a case of re-registration. High-trust, so stripping the E164 from the existing account and assigning it to a new entry.", aci, byE164.get(), e164Settings.aci), true); removePhoneNumber(byE164.get(), db); recipientNeedingRefresh = byE164.get(); - ContentValues insertValues = buildContentValuesForNewUser(e164, uuid); + ContentValues insertValues = buildContentValuesForNewUser(e164, aci); insertValues.put(BLOCKED, e164Settings.blocked ? 1 : 0); long id = db.insert(TABLE_NAME, null, insertValues); finalId = RecipientId.from(id); } else { - Log.w(TAG, String.format(Locale.US, "Found out about a UUID (%s) for a known E164 user (%s), but that user already has a UUID (%s). Likely a case of re-registration. Low-trust, so making a new user for the UUID.", uuid, byE164.get(), e164Settings.uuid), true); + Log.w(TAG, String.format(Locale.US, "Found out about an ACI (%s) for a known E164 user (%s), but that user already has an ACI (%s). Likely a case of re-registration. Low-trust, so making a new user for the UUID.", aci, byE164.get(), e164Settings.aci), true); - long id = db.insert(TABLE_NAME, null, buildContentValuesForNewUser(null, uuid)); + long id = db.insert(TABLE_NAME, null, buildContentValuesForNewUser(null, aci)); finalId = RecipientId.from(id); } } else { if (highTrust) { - Log.i(TAG, String.format(Locale.US, "Found out about a UUID (%s) for a known E164 user (%s). High-trust, so updating.", uuid, byE164.get()), true); - markRegisteredOrThrow(byE164.get(), uuid); + Log.i(TAG, String.format(Locale.US, "Found out about an ACI (%s) for a known E164 user (%s). High-trust, so updating.", aci, byE164.get()), true); + markRegisteredOrThrow(byE164.get(), aci); finalId = byE164.get(); } else { - Log.i(TAG, String.format(Locale.US, "Found out about a UUID (%s) for a known E164 user (%s). Low-trust, so making a new user for the UUID.", uuid, byE164.get()), true); - long id = db.insert(TABLE_NAME, null, buildContentValuesForNewUser(null, uuid)); + Log.i(TAG, String.format(Locale.US, "Found out about an ACI (%s) for a known E164 user (%s). Low-trust, so making a new user for the ACI.", aci, byE164.get()), true); + long id = db.insert(TABLE_NAME, null, buildContentValuesForNewUser(null, aci)); finalId = RecipientId.from(id); } } } else { finalId = byE164.get(); } - } else if (!byE164.isPresent() && byUuid.isPresent()) { + } else if (!byE164.isPresent() && byAci.isPresent()) { if (e164 != null) { if (highTrust) { - if (Objects.equals(uuid, TextSecurePreferences.getLocalUuid(context)) && !changeSelf) { - Log.w(TAG, String.format(Locale.US, "Found out about an E164 (%s) for our own UUID user (%s). High-trust but not change self, doing nothing.", e164, byUuid.get()), true); - finalId = byUuid.get(); + if (Objects.equals(aci, TextSecurePreferences.getLocalAci(context)) && !changeSelf) { + Log.w(TAG, String.format(Locale.US, "Found out about an E164 (%s) for our own ACI user (%s). High-trust but not change self, doing nothing.", e164, byAci.get()), true); + finalId = byAci.get(); } else { - Log.i(TAG, String.format(Locale.US, "Found out about an E164 (%s) for a known UUID user (%s). High-trust, so updating.", e164, byUuid.get()), true); + Log.i(TAG, String.format(Locale.US, "Found out about an E164 (%s) for a known ACI user (%s). High-trust, so updating.", e164, byAci.get()), true); - RecipientSettings byUuidSettings = getRecipientSettings(byUuid.get()); + RecipientSettings byUuidSettings = getRecipientSettings(byAci.get()); - setPhoneNumberOrThrow(byUuid.get(), e164); - finalId = byUuid.get(); + setPhoneNumberOrThrow(byAci.get(), e164); + finalId = byAci.get(); if (!Util.isEmpty(byUuidSettings.e164) && !byUuidSettings.e164.equals(e164)) { recipientChangedNumber = finalId; } } } else { - Log.i(TAG, String.format(Locale.US, "Found out about an E164 (%s) for a known UUID user (%s). Low-trust, so doing nothing.", e164, byUuid.get()), true); - finalId = byUuid.get(); + Log.i(TAG, String.format(Locale.US, "Found out about an E164 (%s) for a known ACI user (%s). Low-trust, so doing nothing.", e164, byAci.get()), true); + finalId = byAci.get(); } } else { - finalId = byUuid.get(); + finalId = byAci.get(); } } else { - if (byE164.equals(byUuid)) { - finalId = byUuid.get(); + if (byE164.equals(byAci)) { + finalId = byAci.get(); } else { - Log.w(TAG, String.format(Locale.US, "Hit a conflict between %s (E164 of %s) and %s (UUID %s). They map to different recipients.", byE164.get(), e164, byUuid.get(), uuid), new Throwable(), true); + Log.w(TAG, String.format(Locale.US, "Hit a conflict between %s (E164 of %s) and %s (ACI %s). They map to different recipients.", byE164.get(), e164, byAci.get(), aci), new Throwable(), true); RecipientSettings e164Settings = getRecipientSettings(byE164.get()); - if (e164Settings.getUuid() != null) { + if (e164Settings.getAci() != null) { if (highTrust) { - Log.w(TAG, "The E164 contact has a different UUID. Likely a case of re-registration. High-trust, so stripping the E164 from the existing account and assigning it to the UUID entry.", true); + Log.w(TAG, "The E164 contact has a different ACI. Likely a case of re-registration. High-trust, so stripping the E164 from the existing account and assigning it to the ACI entry.", true); removePhoneNumber(byE164.get(), db); recipientNeedingRefresh = byE164.get(); - RecipientSettings byUuidSettings = getRecipientSettings(byUuid.get()); + RecipientSettings byUuidSettings = getRecipientSettings(byAci.get()); - setPhoneNumberOrThrow(byUuid.get(), Objects.requireNonNull(e164)); - finalId = byUuid.get(); + setPhoneNumberOrThrow(byAci.get(), Objects.requireNonNull(e164)); + finalId = byAci.get(); if (!Util.isEmpty(byUuidSettings.e164) && !byUuidSettings.e164.equals(e164)) { recipientChangedNumber = finalId; } } else { - Log.w(TAG, "The E164 contact has a different UUID. Likely a case of re-registration. Low-trust, so doing nothing.", true); - finalId = byUuid.get(); + Log.w(TAG, "The E164 contact has a different ACI. Likely a case of re-registration. Low-trust, so doing nothing.", true); + finalId = byAci.get(); } } else { if (highTrust) { - Log.w(TAG, "We have one contact with just an E164, and another with UUID. High-trust, so merging the two rows together.", true); - finalId = merge(byUuid.get(), byE164.get()); - recipientNeedingRefresh = byUuid.get(); - remapped = new Pair<>(byE164.get(), byUuid.get()); + Log.w(TAG, "We have one contact with just an E164, and another with just an ACI. High-trust, so merging the two rows together.", true); + finalId = merge(byAci.get(), byE164.get()); + recipientNeedingRefresh = byAci.get(); + remapped = new Pair<>(byE164.get(), byAci.get()); } else { - Log.w(TAG, "We have one contact with just an E164, and another with UUID. Low-trust, so doing nothing.", true); - finalId = byUuid.get(); + Log.w(TAG, "We have one contact with just an E164, and another with just an ACI. Low-trust, so doing nothing.", true); + finalId = byAci.get(); } } } @@ -592,13 +592,13 @@ public class RecipientDatabase extends Database { } } - private static ContentValues buildContentValuesForNewUser(@Nullable String e164, @Nullable UUID uuid) { + private static ContentValues buildContentValuesForNewUser(@Nullable String e164, @Nullable ACI aci) { ContentValues values = new ContentValues(); values.put(PHONE, e164); - if (uuid != null) { - values.put(UUID, uuid.toString().toLowerCase()); + if (aci != null) { + values.put(ACI_COLUMN, aci.toString().toLowerCase()); values.put(REGISTERED, RegisteredState.REGISTERED.getId()); values.put(STORAGE_SERVICE_ID, Base64.encodeBytes(StorageSyncHelper.generateKey())); values.put(AVATAR_COLOR, AvatarColor.random().serialize()); @@ -608,8 +608,8 @@ public class RecipientDatabase extends Database { } - public @NonNull RecipientId getOrInsertFromUuid(@NonNull UUID uuid) { - return getOrInsertByColumn(UUID, uuid.toString()).recipientId; + public @NonNull RecipientId getOrInsertFromAci(@NonNull ACI aci) { + return getOrInsertByColumn(ACI_COLUMN, aci.toString()).recipientId; } public @NonNull RecipientId getOrInsertFromE164(@NonNull String e164) { @@ -829,13 +829,13 @@ public class RecipientDatabase extends Database { if (id < 0) { Log.w(TAG, "[applyStorageSyncContactInsert] Failed to insert. Possibly merging."); - recipientId = getAndPossiblyMerge(insert.getAddress().hasValidUuid() ? insert.getAddress().getUuid() : null, insert.getAddress().getNumber().get(), true); + recipientId = getAndPossiblyMerge(insert.getAddress().hasValidAci() ? insert.getAddress().getAci() : null, insert.getAddress().getNumber().get(), true); db.update(TABLE_NAME, values, ID_WHERE, SqlUtil.buildArgs(recipientId)); } else { recipientId = RecipientId.from(id); } - if (insert.getIdentityKey().isPresent() && insert.getAddress().hasValidUuid()) { + if (insert.getIdentityKey().isPresent() && insert.getAddress().hasValidAci()) { try { IdentityKey identityKey = new IdentityKey(insert.getIdentityKey().get(), 0); @@ -864,7 +864,7 @@ public class RecipientDatabase extends Database { RecipientId recipientId = getByColumn(STORAGE_SERVICE_ID, Base64.encodeBytes(update.getOld().getId().getRaw())).get(); Log.w(TAG, "[applyStorageSyncContactUpdate] Found user " + recipientId + ". Possibly merging."); - recipientId = getAndPossiblyMerge(update.getNew().getAddress().hasValidUuid() ? update.getNew().getAddress().getUuid() : null, update.getNew().getAddress().getNumber().orNull(), true); + recipientId = getAndPossiblyMerge(update.getNew().getAddress().hasValidAci() ? update.getNew().getAddress().getAci() : null, update.getNew().getAddress().getNumber().orNull(), true); Log.w(TAG, "[applyStorageSyncContactUpdate] Merged into " + recipientId); db.update(TABLE_NAME, values, ID_WHERE, SqlUtil.buildArgs(recipientId)); @@ -881,7 +881,7 @@ public class RecipientDatabase extends Database { try { Optional oldIdentityRecord = identityStore.getIdentityRecord(recipientId); - if (update.getNew().getIdentityKey().isPresent() && update.getNew().getAddress().hasValidUuid()) { + if (update.getNew().getIdentityKey().isPresent() && update.getNew().getAddress().hasValidAci()) { IdentityKey identityKey = new IdentityKey(update.getNew().getIdentityKey().get(), 0); DatabaseFactory.getIdentityDatabase(context).updateIdentityAfterSync(update.getNew().getAddress().getIdentifier(), recipientId, identityKey, StorageSyncModels.remoteToLocalIdentityStatus(update.getNew().getIdentityState())); } @@ -1059,8 +1059,8 @@ public class RecipientDatabase extends Database { ProfileName profileName = ProfileName.fromParts(contact.getGivenName().orNull(), contact.getFamilyName().orNull()); String username = contact.getUsername().orNull(); - if (contact.getAddress().hasValidUuid()) { - values.put(UUID, contact.getAddress().getUuid().toString()); + if (contact.getAddress().hasValidAci()) { + values.put(ACI_COLUMN, contact.getAddress().getAci().toString()); } values.put(PHONE, contact.getAddress().getNumber().orNull()); @@ -1133,9 +1133,9 @@ public class RecipientDatabase extends Database { private List getRecipientSettingsForSync(@Nullable String query, @Nullable String[] args) { SQLiteDatabase db = databaseHelper.getSignalReadableDatabase(); - String table = TABLE_NAME + " LEFT OUTER JOIN " + IdentityDatabase.TABLE_NAME + " ON " + TABLE_NAME + "." + UUID + " = " + IdentityDatabase.TABLE_NAME + "." + IdentityDatabase.ADDRESS - + " LEFT OUTER JOIN " + GroupDatabase.TABLE_NAME + " ON " + TABLE_NAME + "." + GROUP_ID + " = " + GroupDatabase.TABLE_NAME + "." + GroupDatabase.GROUP_ID - + " LEFT OUTER JOIN " + ThreadDatabase.TABLE_NAME + " ON " + TABLE_NAME + "." + ID + " = " + ThreadDatabase.TABLE_NAME + "." + ThreadDatabase.RECIPIENT_ID; + String table = TABLE_NAME + " LEFT OUTER JOIN " + IdentityDatabase.TABLE_NAME + " ON " + TABLE_NAME + "." + ACI_COLUMN + " = " + IdentityDatabase.TABLE_NAME + "." + IdentityDatabase.ADDRESS + + " LEFT OUTER JOIN " + GroupDatabase.TABLE_NAME + " ON " + TABLE_NAME + "." + GROUP_ID + " = " + GroupDatabase.TABLE_NAME + "." + GroupDatabase.GROUP_ID + + " LEFT OUTER JOIN " + ThreadDatabase.TABLE_NAME + " ON " + TABLE_NAME + "." + ID + " = " + ThreadDatabase.TABLE_NAME + "." + ThreadDatabase.RECIPIENT_ID; List out = new ArrayList<>(); String[] columns = Stream.of(TYPED_RECIPIENT_PROJECTION, @@ -1169,7 +1169,7 @@ public class RecipientDatabase extends Database { */ public @NonNull Map getContactStorageSyncIdsMap() { SQLiteDatabase db = databaseHelper.getSignalReadableDatabase(); - String query = STORAGE_SERVICE_ID + " NOT NULL AND " + UUID + " NOT NULL AND " + ID + " != ? AND " + GROUP_TYPE + " != ?"; + String query = STORAGE_SERVICE_ID + " NOT NULL AND " + ACI_COLUMN + " NOT NULL AND " + ID + " != ? AND " + GROUP_TYPE + " != ?"; String[] args = SqlUtil.buildArgs(Recipient.self().getId(), String.valueOf(GroupType.SIGNAL_V2.getId())); Map out = new HashMap<>(); @@ -1215,7 +1215,7 @@ public class RecipientDatabase extends Database { static @NonNull RecipientSettings getRecipientSettings(@NonNull Context context, @NonNull Cursor cursor, @NonNull String idColumnName) { long id = CursorUtil.requireLong(cursor, idColumnName); - UUID uuid = UuidUtil.parseOrNull(CursorUtil.requireString(cursor, UUID)); + ACI uuid = ACI.parseOrNull(CursorUtil.requireString(cursor, ACI_COLUMN)); String username = CursorUtil.requireString(cursor, USERNAME); String e164 = CursorUtil.requireString(cursor, PHONE); String email = CursorUtil.requireString(cursor, EMAIL); @@ -1840,9 +1840,9 @@ public class RecipientDatabase extends Database { * database if missing. */ public Set persistProfileKeySet(@NonNull ProfileKeySet profileKeySet) { - Map profileKeys = profileKeySet.getProfileKeys(); - Map authoritativeProfileKeys = profileKeySet.getAuthoritativeProfileKeys(); - int totalKeys = profileKeys.size() + authoritativeProfileKeys.size(); + Map profileKeys = profileKeySet.getProfileKeys(); + Map authoritativeProfileKeys = profileKeySet.getAuthoritativeProfileKeys(); + int totalKeys = profileKeys.size() + authoritativeProfileKeys.size(); if (totalKeys == 0) { return Collections.emptySet(); @@ -1853,8 +1853,8 @@ public class RecipientDatabase extends Database { HashSet updated = new HashSet<>(totalKeys); RecipientId selfId = Recipient.self().getId(); - for (Map.Entry entry : profileKeys.entrySet()) { - RecipientId recipientId = getOrInsertFromUuid(entry.getKey()); + for (Map.Entry entry : profileKeys.entrySet()) { + RecipientId recipientId = getOrInsertFromAci(entry.getKey()); if (setProfileKeyIfAbsent(recipientId, entry.getValue())) { Log.i(TAG, "Learned new profile key"); @@ -1862,8 +1862,8 @@ public class RecipientDatabase extends Database { } } - for (Map.Entry entry : authoritativeProfileKeys.entrySet()) { - RecipientId recipientId = getOrInsertFromUuid(entry.getKey()); + for (Map.Entry entry : authoritativeProfileKeys.entrySet()) { + RecipientId recipientId = getOrInsertFromAci(entry.getKey()); if (selfId.equals(recipientId)) { Log.i(TAG, "Seen authoritative update for self"); @@ -2111,7 +2111,7 @@ public class RecipientDatabase extends Database { Log.w(TAG, "[setPhoneNumber] Hit a conflict when trying to update " + id + ". Possibly merging."); RecipientSettings existing = getRecipientSettings(id); - RecipientId newId = getAndPossiblyMerge(existing.getUuid(), e164, true); + RecipientId newId = getAndPossiblyMerge(existing.getAci(), e164, true); Log.w(TAG, "[setPhoneNumber] Resulting id: " + newId); db.setTransactionSuccessful(); @@ -2147,7 +2147,7 @@ public class RecipientDatabase extends Database { try { RecipientId id = Recipient.self().getId(); - RecipientId newId = getAndPossiblyMerge(Recipient.self().requireUuid(), e164, true, true); + RecipientId newId = getAndPossiblyMerge(Recipient.self().requireAci(), e164, true, true); if (id.equals(newId)) { Log.i(TAG, "[updateSelfPhone] Phone updated for self"); @@ -2206,19 +2206,19 @@ public class RecipientDatabase extends Database { /** * @return True if setting the UUID resulted in changed recipientId, otherwise false. */ - public boolean markRegistered(@NonNull RecipientId id, @NonNull UUID uuid) { + public boolean markRegistered(@NonNull RecipientId id, @NonNull ACI aci) { SQLiteDatabase db = databaseHelper.getSignalWritableDatabase(); db.beginTransaction(); try { - markRegisteredOrThrow(id, uuid); + markRegisteredOrThrow(id, aci); db.setTransactionSuccessful(); return false; } catch (SQLiteConstraintException e) { Log.w(TAG, "[markRegistered] Hit a conflict when trying to update " + id + ". Possibly merging."); RecipientSettings existing = getRecipientSettings(id); - RecipientId newId = getAndPossiblyMerge(uuid, existing.getE164(), true); + RecipientId newId = getAndPossiblyMerge(aci, existing.getE164(), true); Log.w(TAG, "[markRegistered] Merged into " + newId); db.setTransactionSuccessful(); @@ -2231,10 +2231,10 @@ public class RecipientDatabase extends Database { /** * Should only use if you are confident that this shouldn't result in any contact merging. */ - public void markRegisteredOrThrow(@NonNull RecipientId id, @NonNull UUID uuid) { + public void markRegisteredOrThrow(@NonNull RecipientId id, @NonNull ACI aci) { ContentValues contentValues = new ContentValues(2); contentValues.put(REGISTERED, RegisteredState.REGISTERED.getId()); - contentValues.put(UUID, uuid.toString().toLowerCase()); + contentValues.put(ACI_COLUMN, aci.toString().toLowerCase()); if (update(id, contentValues)) { setStorageIdIfNotSet(id); @@ -2252,28 +2252,31 @@ public class RecipientDatabase extends Database { } } - public void bulkUpdatedRegisteredStatus(@NonNull Map registered, Collection unregistered) { + public void bulkUpdatedRegisteredStatus(@NonNull Map registered, Collection unregistered) { SQLiteDatabase db = databaseHelper.getSignalWritableDatabase(); db.beginTransaction(); try { - for (Map.Entry entry : registered.entrySet()) { + for (Map.Entry entry : registered.entrySet()) { + RecipientId recipientId = entry.getKey(); + ACI aci = entry.getValue(); + ContentValues values = new ContentValues(2); values.put(REGISTERED, RegisteredState.REGISTERED.getId()); - if (entry.getValue() != null) { - values.put(UUID, entry.getValue().toLowerCase()); + if (aci != null) { + values.put(ACI_COLUMN, aci.toString().toLowerCase()); } try { - if (update(entry.getKey(), values)) { - setStorageIdIfNotSet(entry.getKey()); + if (update(recipientId, values)) { + setStorageIdIfNotSet(recipientId); } } catch (SQLiteConstraintException e) { - Log.w(TAG, "[bulkUpdateRegisteredStatus] Hit a conflict when trying to update " + entry.getKey() + ". Possibly merging."); + Log.w(TAG, "[bulkUpdateRegisteredStatus] Hit a conflict when trying to update " + recipientId + ". Possibly merging."); RecipientSettings existing = getRecipientSettings(entry.getKey()); - RecipientId newId = getAndPossiblyMerge(UuidUtil.parseOrThrow(entry.getValue()), existing.getE164(), true); + RecipientId newId = getAndPossiblyMerge(aci, existing.getE164(), true); Log.w(TAG, "[bulkUpdateRegisteredStatus] Merged into " + newId); } } @@ -2298,27 +2301,27 @@ public class RecipientDatabase extends Database { * * @return A mapping of (RecipientId, UUID) */ - public @NonNull Map bulkProcessCdsResult(@NonNull Map mapping) { - SQLiteDatabase db = databaseHelper.getSignalWritableDatabase(); - HashMap uuidMap = new HashMap<>(); + public @NonNull Map bulkProcessCdsResult(@NonNull Map mapping) { + SQLiteDatabase db = databaseHelper.getSignalWritableDatabase(); + HashMap aciMap = new HashMap<>(); db.beginTransaction(); try { - for (Map.Entry entry : mapping.entrySet()) { + for (Map.Entry entry : mapping.entrySet()) { String e164 = entry.getKey(); - UUID uuid = entry.getValue(); - Optional uuidEntry = uuid != null ? getByUuid(uuid) : Optional.absent(); + ACI aci = entry.getValue(); + Optional aciEntry = aci != null ? getByAci(aci) : Optional.absent(); - if (uuidEntry.isPresent()) { - boolean idChanged = setPhoneNumber(uuidEntry.get(), e164); + if (aciEntry.isPresent()) { + boolean idChanged = setPhoneNumber(aciEntry.get(), e164); if (idChanged) { - uuidEntry = getByUuid(Objects.requireNonNull(uuid)); + aciEntry = getByAci(Objects.requireNonNull(aci)); } } - RecipientId id = uuidEntry.isPresent() ? uuidEntry.get() : getOrInsertFromE164(e164); + RecipientId id = aciEntry.isPresent() ? aciEntry.get() : getOrInsertFromE164(e164); - uuidMap.put(id, uuid != null ? uuid.toString() : null); + aciMap.put(id, aci); } db.setTransactionSuccessful(); @@ -2326,7 +2329,7 @@ public class RecipientDatabase extends Database { db.endTransaction(); } - return uuidMap; + return aciMap; } public @NonNull List getUninvitedRecipientsForInsights() { @@ -2730,7 +2733,7 @@ public class RecipientDatabase extends Database { .map(b -> b.getNumber().get()) .toList(); List blockedUuid = Stream.of(blocked) - .map(b -> b.getUuid().toString().toLowerCase()) + .map(b -> b.getAci().toString().toLowerCase()) .toList(); SQLiteDatabase db = databaseHelper.getSignalWritableDatabase(); @@ -2750,7 +2753,7 @@ public class RecipientDatabase extends Database { } for (String uuid : blockedUuid) { - db.update(TABLE_NAME, setBlocked, UUID + " = ?", new String[] { uuid }); + db.update(TABLE_NAME, setBlocked, ACI_COLUMN + " = ?", new String[] { uuid }); } List groupIdStrings = new ArrayList<>(groupIds.size()); @@ -3106,7 +3109,7 @@ public class RecipientDatabase extends Database { SessionDatabase sessionDatabase = DatabaseFactory.getSessionDatabase(context); boolean hasE164Session = sessionDatabase.getAllFor(e164Settings.e164).size() > 0; - boolean hasUuidSession = sessionDatabase.getAllFor(uuidSettings.uuid.toString()).size() > 0; + boolean hasUuidSession = sessionDatabase.getAllFor(uuidSettings.aci.toString()).size() > 0; if (hasE164Session && hasUuidSession) { Log.w(TAG, "Had a session for both users. Deleting the E164.", true); @@ -3114,7 +3117,7 @@ public class RecipientDatabase extends Database { } else if (hasE164Session && !hasUuidSession) { Log.w(TAG, "Had a session for E164, but not UUID. Re-assigning to the UUID.", true); ContentValues values = new ContentValues(); - values.put(SessionDatabase.ADDRESS, uuidSettings.uuid.toString()); + values.put(SessionDatabase.ADDRESS, uuidSettings.aci.toString()); db.update(SessionDatabase.TABLE_NAME, values, SessionDatabase.ADDRESS + " = ?", SqlUtil.buildArgs(e164Settings.e164)); } else if (!hasE164Session && hasUuidSession) { Log.w(TAG, "Had a session for UUID, but not E164. No action necessary.", true); @@ -3260,7 +3263,7 @@ public class RecipientDatabase extends Database { public static class RecipientSettings { private final RecipientId id; - private final UUID uuid; + private final ACI aci; private final String username; private final String e164; private final String email; @@ -3310,7 +3313,7 @@ public class RecipientDatabase extends Database { private final List badges; RecipientSettings(@NonNull RecipientId id, - @Nullable UUID uuid, + @Nullable ACI uuid, @Nullable String username, @Nullable String e164, @Nullable String email, @@ -3355,7 +3358,7 @@ public class RecipientDatabase extends Database { @NonNull List badges) { this.id = id; - this.uuid = uuid; + this.aci = uuid; this.username = username; this.e164 = e164; this.email = email; @@ -3409,8 +3412,8 @@ public class RecipientDatabase extends Database { return id; } - public @Nullable UUID getUuid() { - return uuid; + public @Nullable ACI getAci() { + return aci; } public @Nullable String getUsername() { diff --git a/app/src/main/java/org/thoughtcrime/securesms/database/SenderKeySharedDatabase.java b/app/src/main/java/org/thoughtcrime/securesms/database/SenderKeySharedDatabase.java index a2f41031b1..f497a968f7 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/database/SenderKeySharedDatabase.java +++ b/app/src/main/java/org/thoughtcrime/securesms/database/SenderKeySharedDatabase.java @@ -143,8 +143,8 @@ public class SenderKeySharedDatabase extends Database { SQLiteDatabase db = databaseHelper.getSignalWritableDatabase(); Recipient recipient = Recipient.resolved(recipientId); - if (recipient.hasUuid()) { - db.delete(TABLE_NAME, ADDRESS + " = ?", SqlUtil.buildArgs(recipient.getUuid().get().toString())); + if (recipient.hasAci()) { + db.delete(TABLE_NAME, ADDRESS + " = ?", SqlUtil.buildArgs(recipient.requireAci().toString())); } else { Log.w(TAG, "Recipient doesn't have a UUID! " + recipientId); } diff --git a/app/src/main/java/org/thoughtcrime/securesms/database/SmsDatabase.java b/app/src/main/java/org/thoughtcrime/securesms/database/SmsDatabase.java index dad9459edf..6f54b92095 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/database/SmsDatabase.java +++ b/app/src/main/java/org/thoughtcrime/securesms/database/SmsDatabase.java @@ -723,11 +723,11 @@ public class SmsDatabase extends MessageDatabase { if (!peerEraIdSameAsPrevious && !Util.isEmpty(peekGroupCallEraId)) { Recipient self = Recipient.self(); - boolean markRead = peekJoinedUuids.contains(self.requireUuid()) || self.getId().equals(sender); + boolean markRead = peekJoinedUuids.contains(self.requireAci().uuid()) || self.getId().equals(sender); byte[] updateDetails = GroupCallUpdateDetails.newBuilder() .setEraId(Util.emptyIfNull(peekGroupCallEraId)) - .setStartedCallUuid(Recipient.resolved(sender).requireUuid().toString()) + .setStartedCallUuid(Recipient.resolved(sender).requireAci().toString()) .setStartedCallTimestamp(timestamp) .addAllInCallUuids(Stream.of(peekJoinedUuids).map(UUID::toString).toList()) .setIsCallFull(isCallFull) @@ -804,7 +804,7 @@ public class SmsDatabase extends MessageDatabase { if (!sameEraId && !Util.isEmpty(messageGroupCallEraId)) { byte[] updateDetails = GroupCallUpdateDetails.newBuilder() .setEraId(Util.emptyIfNull(messageGroupCallEraId)) - .setStartedCallUuid(Recipient.resolved(sender).requireUuid().toString()) + .setStartedCallUuid(Recipient.resolved(sender).requireAci().toString()) .setStartedCallTimestamp(timestamp) .addAllInCallUuids(Collections.emptyList()) .setIsCallFull(false) @@ -853,7 +853,7 @@ public class SmsDatabase extends MessageDatabase { } GroupCallUpdateDetails groupCallUpdateDetails = GroupCallUpdateDetailsUtil.parse(record.getBody()); - boolean containsSelf = peekJoinedUuids.contains(Recipient.self().requireUuid()); + boolean containsSelf = peekJoinedUuids.contains(Recipient.self().requireAci().uuid()); sameEraId = groupCallUpdateDetails.getEraId().equals(peekGroupCallEraId) && !Util.isEmpty(peekGroupCallEraId); diff --git a/app/src/main/java/org/thoughtcrime/securesms/database/ThreadDatabase.java b/app/src/main/java/org/thoughtcrime/securesms/database/ThreadDatabase.java index 808b7a3ad2..54f14cd6ab 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/database/ThreadDatabase.java +++ b/app/src/main/java/org/thoughtcrime/securesms/database/ThreadDatabase.java @@ -58,6 +58,7 @@ import org.thoughtcrime.securesms.util.SqlUtil; import org.thoughtcrime.securesms.util.TextSecurePreferences; import org.thoughtcrime.securesms.util.Util; import org.whispersystems.libsignal.util.guava.Optional; +import org.whispersystems.signalservice.api.push.ACI; import org.whispersystems.signalservice.api.storage.SignalAccountRecord; import org.whispersystems.signalservice.api.storage.SignalContactRecord; import org.whispersystems.signalservice.api.storage.SignalGroupV1Record; @@ -1446,7 +1447,7 @@ public class ThreadDatabase extends Database { if (threadRecipient.isPushV2Group()) { MessageRecord.InviteAddState inviteAddState = record.getGv2AddInviteState(); if (inviteAddState != null) { - RecipientId from = RecipientId.from(inviteAddState.getAddedOrInvitedBy(), null); + RecipientId from = RecipientId.from(ACI.from(inviteAddState.getAddedOrInvitedBy()), null); if (inviteAddState.isInvited()) { Log.i(TAG, "GV2 invite message request from " + from); return Extra.forGroupV2invite(from, individualRecipientId); diff --git a/app/src/main/java/org/thoughtcrime/securesms/database/model/GroupCallUpdateMessageFactory.java b/app/src/main/java/org/thoughtcrime/securesms/database/model/GroupCallUpdateMessageFactory.java index 637229c1c0..df03d5abf4 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/database/model/GroupCallUpdateMessageFactory.java +++ b/app/src/main/java/org/thoughtcrime/securesms/database/model/GroupCallUpdateMessageFactory.java @@ -10,26 +10,25 @@ import org.thoughtcrime.securesms.recipients.Recipient; import org.thoughtcrime.securesms.recipients.RecipientId; import org.thoughtcrime.securesms.util.DateUtils; import org.thoughtcrime.securesms.util.TextSecurePreferences; -import org.whispersystems.signalservice.api.util.UuidUtil; +import org.whispersystems.signalservice.api.push.ACI; import java.util.ArrayList; import java.util.List; import java.util.Locale; import java.util.Objects; -import java.util.UUID; /** * Create a group call update message based on time and joined members. */ public class GroupCallUpdateMessageFactory implements UpdateDescription.StringFactory { private final Context context; - private final List joinedMembers; + private final List joinedMembers; private final boolean withTime; private final GroupCallUpdateDetails groupCallUpdateDetails; - private final UUID selfUuid; + private final ACI selfAci; public GroupCallUpdateMessageFactory(@NonNull Context context, - @NonNull List joinedMembers, + @NonNull List joinedMembers, boolean withTime, @NonNull GroupCallUpdateDetails groupCallUpdateDetails) { @@ -37,11 +36,11 @@ public class GroupCallUpdateMessageFactory implements UpdateDescription.StringFa this.joinedMembers = new ArrayList<>(joinedMembers); this.withTime = withTime; this.groupCallUpdateDetails = groupCallUpdateDetails; - this.selfUuid = TextSecurePreferences.getLocalUuid(context); + this.selfAci = TextSecurePreferences.getLocalAci(context); - boolean removed = this.joinedMembers.remove(selfUuid); + boolean removed = this.joinedMembers.remove(selfAci); if (removed) { - this.joinedMembers.add(selfUuid); + this.joinedMembers.add(selfAci); } } @@ -57,7 +56,7 @@ public class GroupCallUpdateMessageFactory implements UpdateDescription.StringFa if (joinedMembers.get(0).toString().equals(groupCallUpdateDetails.getStartedCallUuid())) { return withTime ? context.getString(R.string.MessageRecord_s_started_a_group_call_s, describe(joinedMembers.get(0)), time) : context.getString(R.string.MessageRecord_s_started_a_group_call, describe(joinedMembers.get(0))); - } else if (Objects.equals(joinedMembers.get(0), selfUuid)) { + } else if (Objects.equals(joinedMembers.get(0), selfAci)) { return withTime ? context.getString(R.string.MessageRecord_you_are_in_the_group_call_s1, time) : context.getString(R.string.MessageRecord_you_are_in_the_group_call); } else { @@ -88,12 +87,12 @@ public class GroupCallUpdateMessageFactory implements UpdateDescription.StringFa } } - private @NonNull String describe(@NonNull UUID uuid) { - if (UuidUtil.UNKNOWN_UUID.equals(uuid)) { + private @NonNull String describe(@NonNull ACI aci) { + if (aci.isUnknown()) { return context.getString(R.string.MessageRecord_unknown); } - Recipient recipient = Recipient.resolved(RecipientId.from(uuid, null)); + Recipient recipient = Recipient.resolved(RecipientId.from(aci, null)); if (recipient.isSelf()) { return context.getString(R.string.MessageRecord_you); diff --git a/app/src/main/java/org/thoughtcrime/securesms/database/model/GroupsV2UpdateMessageProducer.java b/app/src/main/java/org/thoughtcrime/securesms/database/model/GroupsV2UpdateMessageProducer.java index 33a2bcf6e4..098e2d6f99 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/database/model/GroupsV2UpdateMessageProducer.java +++ b/app/src/main/java/org/thoughtcrime/securesms/database/model/GroupsV2UpdateMessageProducer.java @@ -26,6 +26,7 @@ import org.thoughtcrime.securesms.util.ExpirationUtil; import org.thoughtcrime.securesms.util.StringUtil; import org.whispersystems.libsignal.util.guava.Optional; import org.whispersystems.signalservice.api.groupsv2.DecryptedGroupUtil; +import org.whispersystems.signalservice.api.push.ACI; import org.whispersystems.signalservice.api.util.UuidUtil; import java.util.Arrays; @@ -744,11 +745,12 @@ final class GroupsV2UpdateMessageProducer { interface DescribeMemberStrategy { /** - * Map a UUID to a string that describes the group member. + * Map an ACI to a string that describes the group member. + * @param aci */ @NonNull @WorkerThread - String describe(@NonNull UUID uuid); + String describe(@NonNull ACI aci); } private interface StringFactory1Arg { @@ -769,9 +771,9 @@ final class GroupsV2UpdateMessageProducer { @NonNull StringFactory1Arg stringFactory, @DrawableRes int iconResource) { - UUID uuid1 = UuidUtil.fromByteStringOrUnknown(uuid1Bytes); + ACI aci1 = ACI.fromByteStringOrUnknown(uuid1Bytes); - return UpdateDescription.mentioning(Collections.singletonList(uuid1), () -> stringFactory.create(descriptionStrategy.describe(uuid1)), iconResource); + return UpdateDescription.mentioning(Collections.singletonList(aci1), () -> stringFactory.create(descriptionStrategy.describe(aci1)), iconResource); } private UpdateDescription updateDescription(@NonNull ByteString uuid1Bytes, @@ -779,9 +781,9 @@ final class GroupsV2UpdateMessageProducer { @NonNull StringFactory2Args stringFactory, @DrawableRes int iconResource) { - UUID uuid1 = UuidUtil.fromByteStringOrUnknown(uuid1Bytes); - UUID uuid2 = UuidUtil.fromByteStringOrUnknown(uuid2Bytes); + ACI aci1 = ACI.fromByteStringOrUnknown(uuid1Bytes); + ACI aci2 = ACI.fromByteStringOrUnknown(uuid2Bytes); - return UpdateDescription.mentioning(Arrays.asList(uuid1, uuid2), () -> stringFactory.create(descriptionStrategy.describe(uuid1), descriptionStrategy.describe(uuid2)), iconResource); + return UpdateDescription.mentioning(Arrays.asList(aci1, aci2), () -> stringFactory.create(descriptionStrategy.describe(aci1), descriptionStrategy.describe(aci2)), iconResource); } } \ No newline at end of file diff --git a/app/src/main/java/org/thoughtcrime/securesms/database/model/MessageRecord.java b/app/src/main/java/org/thoughtcrime/securesms/database/model/MessageRecord.java index 4cf67f62c6..e9fe98df5e 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/database/model/MessageRecord.java +++ b/app/src/main/java/org/thoughtcrime/securesms/database/model/MessageRecord.java @@ -54,6 +54,7 @@ import org.thoughtcrime.securesms.util.StringUtil; import org.thoughtcrime.securesms.util.Util; import org.whispersystems.libsignal.util.guava.Function; import org.whispersystems.signalservice.api.groupsv2.DecryptedGroupUtil; +import org.whispersystems.signalservice.api.push.ACI; import org.whispersystems.signalservice.api.util.UuidUtil; import java.io.IOException; @@ -240,7 +241,7 @@ public abstract class MessageRecord extends DisplayRecord { private static boolean selfCreatedGroup(@NonNull DecryptedGroupChange change) { return change.getRevision() == 0 && - change.getEditor().equals(UuidUtil.toByteString(Recipient.self().requireUuid())); + change.getEditor().equals(UuidUtil.toByteString(Recipient.self().requireAci().uuid())); } public static @NonNull UpdateDescription getGv2ChangeDescription(@NonNull Context context, @NonNull String body) { @@ -248,7 +249,7 @@ public abstract class MessageRecord extends DisplayRecord { ShortStringDescriptionStrategy descriptionStrategy = new ShortStringDescriptionStrategy(context); byte[] decoded = Base64.decode(body); DecryptedGroupV2Context decryptedGroupV2Context = DecryptedGroupV2Context.parseFrom(decoded); - GroupsV2UpdateMessageProducer updateMessageProducer = new GroupsV2UpdateMessageProducer(context, descriptionStrategy, Recipient.self().getUuid().get()); + GroupsV2UpdateMessageProducer updateMessageProducer = new GroupsV2UpdateMessageProducer(context, descriptionStrategy, Recipient.self().requireAci().uuid()); if (decryptedGroupV2Context.hasChange() && (decryptedGroupV2Context.getGroupState().getRevision() != 0 || decryptedGroupV2Context.hasPreviousGroupState())) { return UpdateDescription.concatWithNewLines(updateMessageProducer.describeChanges(decryptedGroupV2Context.getPreviousGroupState(), decryptedGroupV2Context.getChange())); @@ -279,7 +280,7 @@ public abstract class MessageRecord extends DisplayRecord { } DecryptedGroup groupState = decryptedGroupV2Context.getGroupState(); - boolean invited = DecryptedGroupUtil.findPendingByUuid(groupState.getPendingMembersList(), Recipient.self().requireUuid()).isPresent(); + boolean invited = DecryptedGroupUtil.findPendingByUuid(groupState.getPendingMembersList(), Recipient.self().requireAci().uuid()).isPresent(); if (decryptedGroupV2Context.hasChange()) { UUID changeEditor = UuidUtil.fromByteStringOrNull(decryptedGroupV2Context.getChange().getEditor()); @@ -301,7 +302,7 @@ public abstract class MessageRecord extends DisplayRecord { @NonNull Function stringGenerator, @DrawableRes int iconResource) { - return UpdateDescription.mentioning(Collections.singletonList(recipient.getUuid().or(UuidUtil.UNKNOWN_UUID)), + return UpdateDescription.mentioning(Collections.singletonList(recipient.getAci().or(ACI.UNKNOWN)), () -> stringGenerator.apply(recipient.resolve()), iconResource); } @@ -369,10 +370,11 @@ public abstract class MessageRecord extends DisplayRecord { public static @NonNull UpdateDescription getGroupCallUpdateDescription(@NonNull Context context, @NonNull String body, boolean withTime) { GroupCallUpdateDetails groupCallUpdateDetails = GroupCallUpdateDetailsUtil.parse(body); - List joinedMembers = Stream.of(groupCallUpdateDetails.getInCallUuidsList()) - .map(UuidUtil::parseOrNull) - .withoutNulls() - .toList(); + List joinedMembers = Stream.of(groupCallUpdateDetails.getInCallUuidsList()) + .map(UuidUtil::parseOrNull) + .withoutNulls() + .map(ACI::from) + .toList(); UpdateDescription.StringFactory stringFactory = new GroupCallUpdateMessageFactory(context, joinedMembers, withTime, groupCallUpdateDetails); @@ -407,11 +409,11 @@ public abstract class MessageRecord extends DisplayRecord { } @Override - public @NonNull String describe(@NonNull UUID uuid) { - if (UuidUtil.UNKNOWN_UUID.equals(uuid)) { + public @NonNull String describe(@NonNull ACI aci) { + if (aci.isUnknown()) { return context.getString(R.string.MessageRecord_unknown); } - return Recipient.resolved(RecipientId.from(uuid, null)).getDisplayName(context); + return Recipient.resolved(RecipientId.from(aci, null)).getDisplayName(context); } } diff --git a/app/src/main/java/org/thoughtcrime/securesms/database/model/UpdateDescription.java b/app/src/main/java/org/thoughtcrime/securesms/database/model/UpdateDescription.java index 8d3f54793a..c92675cf24 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/database/model/UpdateDescription.java +++ b/app/src/main/java/org/thoughtcrime/securesms/database/model/UpdateDescription.java @@ -8,6 +8,7 @@ import androidx.annotation.Nullable; import androidx.annotation.WorkerThread; import org.signal.core.util.ThreadUtil; +import org.whispersystems.signalservice.api.push.ACI; import org.whispersystems.signalservice.api.util.UuidUtil; import java.util.Collection; @@ -27,14 +28,14 @@ public final class UpdateDescription { String create(); } - private final Collection mentioned; - private final StringFactory stringFactory; - private final String staticString; - private final int lightIconResource; - private final int lightTint; - private final int darkTint; + private final Collection mentioned; + private final StringFactory stringFactory; + private final String staticString; + private final int lightIconResource; + private final int lightTint; + private final int darkTint; - private UpdateDescription(@NonNull Collection mentioned, + private UpdateDescription(@NonNull Collection mentioned, @Nullable StringFactory stringFactory, @Nullable String staticString, @DrawableRes int iconResource, @@ -59,11 +60,11 @@ public final class UpdateDescription { * @param mentioned UUIDs of recipients that are mentioned in the string. * @param stringFactory The background method for generating the string. */ - public static UpdateDescription mentioning(@NonNull Collection mentioned, + public static UpdateDescription mentioning(@NonNull Collection mentioned, @NonNull StringFactory stringFactory, @DrawableRes int iconResource) { - return new UpdateDescription(UuidUtil.filterKnown(mentioned), + return new UpdateDescription(ACI.filterKnown(mentioned), stringFactory, null, iconResource, @@ -117,7 +118,7 @@ public final class UpdateDescription { } @AnyThread - public Collection getMentioned() { + public Collection getMentioned() { return mentioned; } @@ -148,7 +149,7 @@ public final class UpdateDescription { ); } - Set allMentioned = new HashSet<>(); + Set allMentioned = new HashSet<>(); for (UpdateDescription updateDescription : updateDescriptions) { allMentioned.addAll(updateDescription.getMentioned()); 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 3c60cd671a..4d6aa820db 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/dependencies/ApplicationDependencyProvider.java +++ b/app/src/main/java/org/thoughtcrime/securesms/dependencies/ApplicationDependencyProvider.java @@ -72,6 +72,7 @@ import org.whispersystems.signalservice.api.SignalServiceMessageSender; import org.whispersystems.signalservice.api.SignalWebSocket; import org.whispersystems.signalservice.api.groupsv2.ClientZkOperations; import org.whispersystems.signalservice.api.groupsv2.GroupsV2Operations; +import org.whispersystems.signalservice.api.push.ACI; import org.whispersystems.signalservice.api.services.DonationsService; import org.whispersystems.signalservice.api.util.CredentialsProvider; import org.whispersystems.signalservice.api.util.SleepTimer; @@ -79,7 +80,6 @@ import org.whispersystems.signalservice.api.util.UptimeSleepTimer; import org.whispersystems.signalservice.api.websocket.WebSocketFactory; import org.whispersystems.signalservice.internal.websocket.WebSocketConnection; -import java.util.UUID; import java.util.concurrent.TimeUnit; /** @@ -359,8 +359,8 @@ public class ApplicationDependencyProvider implements ApplicationDependencies.Pr } @Override - public UUID getUuid() { - return TextSecurePreferences.getLocalUuid(context); + public ACI getAci() { + return TextSecurePreferences.getLocalAci(context); } @Override diff --git a/app/src/main/java/org/thoughtcrime/securesms/groups/GroupManagerV2.java b/app/src/main/java/org/thoughtcrime/securesms/groups/GroupManagerV2.java index 4cf09b02eb..20a0498548 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/groups/GroupManagerV2.java +++ b/app/src/main/java/org/thoughtcrime/securesms/groups/GroupManagerV2.java @@ -60,6 +60,7 @@ import org.whispersystems.signalservice.api.groupsv2.GroupsV2Api; import org.whispersystems.signalservice.api.groupsv2.GroupsV2Operations; import org.whispersystems.signalservice.api.groupsv2.InvalidGroupStateException; import org.whispersystems.signalservice.api.groupsv2.NotAbleToApplyGroupV2ChangeException; +import org.whispersystems.signalservice.api.push.ACI; import org.whispersystems.signalservice.api.push.exceptions.AuthorizationFailedException; import org.whispersystems.signalservice.api.push.exceptions.ConflictException; import org.whispersystems.signalservice.api.util.UuidUtil; @@ -92,7 +93,7 @@ final class GroupManagerV2 { private final GroupsV2Operations groupsV2Operations; private final GroupsV2Authorization authorization; private final GroupsV2StateProcessor groupsV2StateProcessor; - private final UUID selfUuid; + private final ACI selfAci; private final GroupCandidateHelper groupCandidateHelper; GroupManagerV2(@NonNull Context context) { @@ -102,7 +103,7 @@ final class GroupManagerV2 { this.groupsV2Operations = ApplicationDependencies.getGroupsV2Operations(); this.authorization = ApplicationDependencies.getGroupsV2Authorization(); this.groupsV2StateProcessor = ApplicationDependencies.getGroupsV2StateProcessor(); - this.selfUuid = Recipient.self().getUuid().get(); + this.selfAci = Recipient.self().requireAci(); this.groupCandidateHelper = new GroupCandidateHelper(context); } @@ -113,7 +114,7 @@ final class GroupManagerV2 { return groupsV2Api.getGroupJoinInfo(groupSecretParams, Optional.fromNullable(password).transform(GroupLinkPassword::serialize), - authorization.getAuthorizationForToday(Recipient.self().requireUuid(), groupSecretParams)); + authorization.getAuthorizationForToday(selfAci, groupSecretParams)); } @WorkerThread @@ -127,7 +128,7 @@ final class GroupManagerV2 { GroupSecretParams groupSecretParams = GroupSecretParams.deriveFromMasterKey(groupMasterKey); - return groupsV2Api.getGroupExternalCredential(authorization.getAuthorizationForToday(Recipient.self().requireUuid(), groupSecretParams)); + return groupsV2Api.getGroupExternalCredential(authorization.getAuthorizationForToday(selfAci, groupSecretParams)); } @WorkerThread @@ -140,7 +141,7 @@ final class GroupManagerV2 { Map uuidCipherTexts = new HashMap<>(); for (Recipient recipient : recipients) { - uuidCipherTexts.put(recipient.requireUuid(), clientZkGroupCipher.encryptUuid(recipient.requireUuid())); + uuidCipherTexts.put(recipient.requireAci().uuid(), clientZkGroupCipher.encryptUuid(recipient.requireAci().uuid())); } return uuidCipherTexts; @@ -195,7 +196,7 @@ final class GroupManagerV2 { return latest; } - Optional selfInFullMemberList = DecryptedGroupUtil.findMemberByUuid(latest.getMembersList(), Recipient.self().requireUuid()); + Optional selfInFullMemberList = DecryptedGroupUtil.findMemberByUuid(latest.getMembersList(), selfAci.uuid()); if (!selfInFullMemberList.isPresent()) { return latest; @@ -267,7 +268,7 @@ final class GroupManagerV2 { DatabaseFactory.getRecipientDatabase(context).setProfileSharing(groupRecipient.getId(), true); DecryptedGroupChange groupChange = DecryptedGroupChange.newBuilder(GroupChangeReconstruct.reconstructGroupChange(DecryptedGroup.newBuilder().build(), decryptedGroup)) - .setEditor(UuidUtil.toByteString(selfUuid)) + .setEditor(selfAci.toByteString()) .build(); RecipientAndThread recipientAndThread = sendGroupUpdate(masterKey, new GroupMutation(null, groupChange, decryptedGroup), null); @@ -312,7 +313,7 @@ final class GroupManagerV2 { groupCandidates = GroupCandidate.withoutProfileKeyCredentials(groupCandidates); } - return commitChangeWithConflictResolution(groupOperations.createModifyGroupMembershipChange(groupCandidates, selfUuid)); + return commitChangeWithConflictResolution(groupOperations.createModifyGroupMembershipChange(groupCandidates, selfAci.uuid())); } @WorkerThread @@ -356,7 +357,7 @@ final class GroupManagerV2 { } if (avatarChanged) { - String cdnKey = avatarBytes != null ? groupsV2Api.uploadAvatar(avatarBytes, groupSecretParams, authorization.getAuthorizationForToday(selfUuid, groupSecretParams)) + String cdnKey = avatarBytes != null ? groupsV2Api.uploadAvatar(avatarBytes, groupSecretParams, authorization.getAuthorizationForToday(selfAci, groupSecretParams)) : ""; change.setModifyAvatar(GroupChange.Actions.ModifyAvatarAction.newBuilder() .setAvatar(cdnKey)); @@ -387,7 +388,7 @@ final class GroupManagerV2 { throws GroupChangeFailedException, GroupInsufficientRightsException, IOException, GroupNotAMemberException { Set uuids = Stream.of(recipientIds) - .map(r -> Recipient.resolved(r).getUuid().get()) + .map(r -> Recipient.resolved(r).requireAci().uuid()) .collect(Collectors.toSet()); return commitChangeWithConflictResolution(groupOperations.createApproveGroupJoinRequest(uuids)); @@ -398,7 +399,7 @@ final class GroupManagerV2 { throws GroupChangeFailedException, GroupInsufficientRightsException, IOException, GroupNotAMemberException { Set uuids = Stream.of(recipientIds) - .map(r -> Recipient.resolved(r).getUuid().get()) + .map(r -> Recipient.resolved(r).requireAci().uuid()) .collect(Collectors.toSet()); return commitChangeWithConflictResolution(groupOperations.createRefuseGroupJoinRequest(uuids)); @@ -410,7 +411,7 @@ final class GroupManagerV2 { throws GroupChangeFailedException, GroupInsufficientRightsException, IOException, GroupNotAMemberException { Recipient recipient = Recipient.resolved(recipientId); - return commitChangeWithConflictResolution(groupOperations.createChangeMemberRole(recipient.getUuid().get(), admin ? Member.Role.ADMINISTRATOR : Member.Role.DEFAULT)); + return commitChangeWithConflictResolution(groupOperations.createChangeMemberRole(recipient.requireAci().uuid(), admin ? Member.Role.ADMINISTRATOR : Member.Role.DEFAULT)); } @WorkerThread @@ -420,7 +421,7 @@ final class GroupManagerV2 { Recipient self = Recipient.self(); GroupDatabase.GroupRecord groupRecord = groupDatabase.getGroup(groupId).get(); List pendingMembersList = groupRecord.requireV2GroupProperties().getDecryptedGroup().getPendingMembersList(); - Optional selfPendingMember = DecryptedGroupUtil.findPendingByUuid(pendingMembersList, selfUuid); + Optional selfPendingMember = DecryptedGroupUtil.findPendingByUuid(pendingMembersList, selfAci.uuid()); if (selfPendingMember.isPresent()) { try { @@ -439,7 +440,7 @@ final class GroupManagerV2 { { Recipient recipient = Recipient.resolved(recipientId); - return commitChangeWithConflictResolution(groupOperations.createRemoveMembersChange(Collections.singleton(recipient.getUuid().get()))); + return commitChangeWithConflictResolution(groupOperations.createRemoveMembersChange(Collections.singleton(recipient.requireAci().uuid()))); } @WorkerThread @@ -447,9 +448,9 @@ final class GroupManagerV2 { throws GroupChangeFailedException, GroupNotAMemberException, GroupInsufficientRightsException, IOException { Recipient self = Recipient.self(); - List newAdminRecipients = Stream.of(newAdmins).map(id -> Recipient.resolved(id).getUuid().get()).toList(); + List newAdminRecipients = Stream.of(newAdmins).map(id -> Recipient.resolved(id).requireAci().uuid()).toList(); - return commitChangeWithConflictResolution(groupOperations.createLeaveAndPromoteMembersToAdmin(self.getUuid().get(), + return commitChangeWithConflictResolution(groupOperations.createLeaveAndPromoteMembersToAdmin(selfAci.uuid(), newAdminRecipients)); } @@ -459,7 +460,7 @@ final class GroupManagerV2 { { ProfileKey profileKey = ProfileKeyUtil.getSelfProfileKey(); DecryptedGroup group = groupDatabase.requireGroup(groupId).requireV2GroupProperties().getDecryptedGroup(); - Optional selfInGroup = DecryptedGroupUtil.findMemberByUuid(group.getMembersList(), selfUuid); + Optional selfInGroup = DecryptedGroupUtil.findMemberByUuid(group.getMembersList(), selfAci.uuid()); if (!selfInGroup.isPresent()) { Log.w(TAG, "Self not in group " + groupId); @@ -489,7 +490,7 @@ final class GroupManagerV2 { throws GroupChangeFailedException, GroupInsufficientRightsException, IOException, GroupNotAMemberException { DecryptedGroup group = groupDatabase.requireGroup(groupId).requireV2GroupProperties().getDecryptedGroup(); - Optional selfInGroup = DecryptedGroupUtil.findMemberByUuid(group.getMembersList(), Recipient.self().getUuid().get()); + Optional selfInGroup = DecryptedGroupUtil.findMemberByUuid(group.getMembersList(), selfAci.uuid()); if (selfInGroup.isPresent()) { Log.w(TAG, "Self already in group"); @@ -553,7 +554,7 @@ final class GroupManagerV2 { private @NonNull GroupManager.GroupActionResult commitChangeWithConflictResolution(@NonNull GroupChange.Actions.Builder change) throws GroupChangeFailedException, GroupNotAMemberException, GroupInsufficientRightsException, IOException { - change.setSourceUuid(UuidUtil.toByteString(Recipient.self().getUuid().get())); + change.setSourceUuid(UuidUtil.toByteString(selfAci.uuid())); for (int attempt = 0; attempt < 5; attempt++) { try { @@ -602,7 +603,7 @@ final class GroupManagerV2 { GroupChange.Actions changeActions = change.build(); return GroupChangeUtil.resolveConflict(groupUpdateResult.getLatestServer(), - groupOperations.decryptChange(changeActions, selfUuid), + groupOperations.decryptChange(changeActions, selfAci.uuid()), changeActions); } catch (VerificationFailedException | InvalidGroupStateException ex) { throw new GroupChangeFailedException(ex); @@ -622,7 +623,7 @@ final class GroupManagerV2 { try { previousGroupState = v2GroupProperties.getDecryptedGroup(); - decryptedChange = groupOperations.decryptChange(changeActions, selfUuid); + decryptedChange = groupOperations.decryptChange(changeActions, selfAci.uuid()); decryptedGroupState = DecryptedGroupUtil.apply(previousGroupState, decryptedChange); } catch (VerificationFailedException | InvalidGroupStateException | NotAbleToApplyGroupV2ChangeException e) { Log.w(TAG, e); @@ -644,7 +645,7 @@ final class GroupManagerV2 { throws GroupNotAMemberException, GroupChangeFailedException, IOException, GroupInsufficientRightsException { try { - return groupsV2Api.patchGroup(change, authorization.getAuthorizationForToday(selfUuid, groupSecretParams), Optional.absent()); + return groupsV2Api.patchGroup(change, authorization.getAuthorizationForToday(selfAci, groupSecretParams), Optional.absent()); } catch (NotInGroupException e) { Log.w(TAG, e); throw new GroupNotAMemberException(e); @@ -727,9 +728,9 @@ final class GroupManagerV2 { disappearingMessageTimerSeconds); try { - groupsV2Api.putNewGroup(newGroup, authorization.getAuthorizationForToday(Recipient.self().requireUuid(), groupSecretParams)); + groupsV2Api.putNewGroup(newGroup, authorization.getAuthorizationForToday(selfAci, groupSecretParams)); - DecryptedGroup decryptedGroup = groupsV2Api.getGroup(groupSecretParams, ApplicationDependencies.getGroupsV2Authorization().getAuthorizationForToday(Recipient.self().requireUuid(), groupSecretParams)); + DecryptedGroup decryptedGroup = groupsV2Api.getGroup(groupSecretParams, ApplicationDependencies.getGroupsV2Authorization().getAuthorizationForToday(selfAci, groupSecretParams)); if (decryptedGroup == null) { throw new GroupChangeFailedException(); } @@ -922,7 +923,7 @@ final class GroupManagerV2 { .setRevision(GroupsV2StateProcessor.PLACEHOLDER_REVISION); Recipient self = Recipient.self(); - ByteString selfUuid = UuidUtil.toByteString(self.requireUuid()); + ByteString selfUuid = selfAci.toByteString(); ByteString profileKey = ByteString.copyFrom(Objects.requireNonNull(self.getProfileKey())); if (requestToJoin) { @@ -956,7 +957,7 @@ final class GroupManagerV2 { GroupChange.Actions.Builder change = requestToJoin ? groupOperations.createGroupJoinRequest(profileKeyCredential) : groupOperations.createGroupJoinDirect(profileKeyCredential); - change.setSourceUuid(UuidUtil.toByteString(Recipient.self().getUuid().get())); + change.setSourceUuid(selfAci.toByteString()); return commitJoinChangeWithConflictResolution(currentRevision, change); } @@ -1000,7 +1001,7 @@ final class GroupManagerV2 { throws GroupChangeFailedException, IOException, GroupLinkNotActiveException { try { - return groupsV2Api.patchGroup(change, authorization.getAuthorizationForToday(selfUuid, groupSecretParams), Optional.fromNullable(password).transform(GroupLinkPassword::serialize)); + return groupsV2Api.patchGroup(change, authorization.getAuthorizationForToday(selfAci, groupSecretParams), Optional.fromNullable(password).transform(GroupLinkPassword::serialize)); } catch (NotInGroupException | VerificationFailedException e) { Log.w(TAG, e); throw new GroupChangeFailedException(e); @@ -1044,7 +1045,7 @@ final class GroupManagerV2 { throws IOException, VerificationFailedException, InvalidGroupStateException { try { - groupsV2Api.getGroup(groupSecretParams, authorization.getAuthorizationForToday(Recipient.self().requireUuid(), groupSecretParams)); + groupsV2Api.getGroup(groupSecretParams, authorization.getAuthorizationForToday(selfAci, groupSecretParams)); return true; } catch (NotInGroupException ex) { return false; @@ -1055,7 +1056,7 @@ final class GroupManagerV2 { void cancelJoinRequest() throws GroupChangeFailedException, IOException { - Set uuids = Collections.singleton(Recipient.self().getUuid().get()); + Set uuids = Collections.singleton(selfAci.uuid()); GroupChange signedGroupChange; try { @@ -1158,7 +1159,7 @@ final class GroupManagerV2 { private static @NonNull List getPendingMemberRecipientIds(@NonNull List newPendingMembersList) { return Stream.of(DecryptedGroupUtil.pendingToUuidList(newPendingMembersList)) - .map(uuid-> RecipientId.from(uuid,null)) + .map(uuid -> RecipientId.from(ACI.from(uuid), null)) .toList(); } diff --git a/app/src/main/java/org/thoughtcrime/securesms/groups/GroupProtoUtil.java b/app/src/main/java/org/thoughtcrime/securesms/groups/GroupProtoUtil.java index 1a0d290a7f..8702cf0d9b 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/groups/GroupProtoUtil.java +++ b/app/src/main/java/org/thoughtcrime/securesms/groups/GroupProtoUtil.java @@ -19,6 +19,7 @@ import org.thoughtcrime.securesms.database.model.databaseprotos.DecryptedGroupV2 import org.thoughtcrime.securesms.recipients.Recipient; import org.thoughtcrime.securesms.recipients.RecipientId; import org.whispersystems.signalservice.api.groupsv2.GroupsV2Operations; +import org.whispersystems.signalservice.api.push.ACI; import org.whispersystems.signalservice.api.util.UuidUtil; import org.whispersystems.signalservice.internal.push.SignalServiceProtos; @@ -85,27 +86,26 @@ public final class GroupProtoUtil { @WorkerThread public static Recipient uuidByteStringToRecipient(@NonNull Context context, @NonNull ByteString uuidByteString) { - UUID uuid = UUIDUtil.deserialize(uuidByteString.toByteArray()); + ACI aci = ACI.fromByteString(uuidByteString); - if (uuid.equals(GroupsV2Operations.UNKNOWN_UUID)) { + if (aci.isUnknown()) { return Recipient.UNKNOWN; } - return Recipient.externalPush(context, uuid, null, false); + return Recipient.externalPush(context, aci, null, false); } @WorkerThread public static @NonNull RecipientId uuidByteStringToRecipientId(@NonNull ByteString uuidByteString) { - UUID uuid = UUIDUtil.deserialize(uuidByteString.toByteArray()); + ACI aci = ACI.fromByteString(uuidByteString); - if (uuid.equals(GroupsV2Operations.UNKNOWN_UUID)) { + if (aci.isUnknown()) { return RecipientId.UNKNOWN; } - return RecipientId.from(uuid, null); + return RecipientId.from(aci, null); } - public static boolean isMember(@NonNull UUID uuid, @NonNull List membersList) { ByteString uuidBytes = UuidUtil.toByteString(uuid); diff --git a/app/src/main/java/org/thoughtcrime/securesms/groups/GroupsV1MigrationUtil.java b/app/src/main/java/org/thoughtcrime/securesms/groups/GroupsV1MigrationUtil.java index b33c01df51..f7600f17d8 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/groups/GroupsV1MigrationUtil.java +++ b/app/src/main/java/org/thoughtcrime/securesms/groups/GroupsV1MigrationUtil.java @@ -232,10 +232,10 @@ public final class GroupsV1MigrationUtil { * True if the user meets all the requirements to be auto-migrated, otherwise false. */ public static boolean isAutoMigratable(@NonNull Recipient recipient) { - return recipient.hasUuid() && - recipient.getGroupsV2Capability() == Recipient.Capability.SUPPORTED && + return recipient.hasAci() && + recipient.getGroupsV2Capability() == Recipient.Capability.SUPPORTED && recipient.getGroupsV1MigrationCapability() == Recipient.Capability.SUPPORTED && - recipient.getRegistered() == RecipientDatabase.RegisteredState.REGISTERED && + recipient.getRegistered() == RecipientDatabase.RegisteredState.REGISTERED && recipient.getProfileKey() != null; } diff --git a/app/src/main/java/org/thoughtcrime/securesms/groups/GroupsV2Authorization.java b/app/src/main/java/org/thoughtcrime/securesms/groups/GroupsV2Authorization.java index 42ecd75400..c9196b017b 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/groups/GroupsV2Authorization.java +++ b/app/src/main/java/org/thoughtcrime/securesms/groups/GroupsV2Authorization.java @@ -9,6 +9,7 @@ import org.signal.zkgroup.groups.GroupSecretParams; import org.whispersystems.signalservice.api.groupsv2.GroupsV2Api; import org.whispersystems.signalservice.api.groupsv2.GroupsV2AuthorizationString; import org.whispersystems.signalservice.api.groupsv2.NoCredentialForRedemptionTimeException; +import org.whispersystems.signalservice.api.push.ACI; import java.io.IOException; import java.util.Map; @@ -27,7 +28,7 @@ public final class GroupsV2Authorization { this.cache = cache; } - public GroupsV2AuthorizationString getAuthorizationForToday(@NonNull UUID self, + public GroupsV2AuthorizationString getAuthorizationForToday(@NonNull ACI self, @NonNull GroupSecretParams groupSecretParams) throws IOException, VerificationFailedException { @@ -65,7 +66,7 @@ public final class GroupsV2Authorization { return (int) TimeUnit.MILLISECONDS.toDays(System.currentTimeMillis()); } - private GroupsV2AuthorizationString getAuthorization(UUID self, + private GroupsV2AuthorizationString getAuthorization(ACI self, GroupSecretParams groupSecretParams, Map credentials, int today) diff --git a/app/src/main/java/org/thoughtcrime/securesms/groups/GroupsV2CapabilityChecker.java b/app/src/main/java/org/thoughtcrime/securesms/groups/GroupsV2CapabilityChecker.java index e3919b12b6..a8296e7159 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/groups/GroupsV2CapabilityChecker.java +++ b/app/src/main/java/org/thoughtcrime/securesms/groups/GroupsV2CapabilityChecker.java @@ -86,7 +86,7 @@ public final class GroupsV2CapabilityChecker { } } - if (!member.hasUuid()) { + if (!member.hasAci()) { noUuidCount++; } } diff --git a/app/src/main/java/org/thoughtcrime/securesms/groups/LiveGroup.java b/app/src/main/java/org/thoughtcrime/securesms/groups/LiveGroup.java index 5fe1498abb..89387aed2f 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/groups/LiveGroup.java +++ b/app/src/main/java/org/thoughtcrime/securesms/groups/LiveGroup.java @@ -27,6 +27,7 @@ import org.thoughtcrime.securesms.recipients.LiveRecipient; import org.thoughtcrime.securesms.recipients.Recipient; import org.thoughtcrime.securesms.recipients.RecipientId; import org.thoughtcrime.securesms.util.livedata.LiveDataUtil; +import org.whispersystems.signalservice.api.push.ACI; import org.whispersystems.signalservice.api.util.UuidUtil; import java.util.Collections; @@ -108,7 +109,7 @@ public final class LiveGroup { return Stream.of(requestingMembersList) .map(requestingMember -> { - Recipient recipient = Recipient.externalPush(ApplicationDependencies.getApplication(), UuidUtil.fromByteString(requestingMember.getUuid()), null, false); + Recipient recipient = Recipient.externalPush(ApplicationDependencies.getApplication(), ACI.fromByteString(requestingMember.getUuid()), null, false); return new GroupMemberEntry.RequestingMember(recipient, selfAdmin); }) .toList(); diff --git a/app/src/main/java/org/thoughtcrime/securesms/groups/ui/invitesandrequests/invited/PendingMemberInvitesRepository.java b/app/src/main/java/org/thoughtcrime/securesms/groups/ui/invitesandrequests/invited/PendingMemberInvitesRepository.java index 95aa9adefb..5f15f64cf9 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/groups/ui/invitesandrequests/invited/PendingMemberInvitesRepository.java +++ b/app/src/main/java/org/thoughtcrime/securesms/groups/ui/invitesandrequests/invited/PendingMemberInvitesRepository.java @@ -55,7 +55,7 @@ final class PendingMemberInvitesRepository { List pendingMembersList = decryptedGroup.getPendingMembersList(); List byMe = new ArrayList<>(pendingMembersList.size()); List byOthers = new ArrayList<>(pendingMembersList.size()); - ByteString self = ByteString.copyFrom(UUIDUtil.serialize(Recipient.self().getUuid().get())); + ByteString self = Recipient.self().requireAci().toByteString(); boolean selfIsAdmin = v2GroupProperties.isAdmin(Recipient.self()); Stream.of(pendingMembersList) diff --git a/app/src/main/java/org/thoughtcrime/securesms/groups/ui/migration/GroupsV1MigrationRepository.java b/app/src/main/java/org/thoughtcrime/securesms/groups/ui/migration/GroupsV1MigrationRepository.java index 998e93bebf..f053a7724b 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/groups/ui/migration/GroupsV1MigrationRepository.java +++ b/app/src/main/java/org/thoughtcrime/securesms/groups/ui/migration/GroupsV1MigrationRepository.java @@ -20,7 +20,6 @@ import org.thoughtcrime.securesms.recipients.Recipient; import org.thoughtcrime.securesms.recipients.RecipientId; import org.thoughtcrime.securesms.recipients.RecipientUtil; import org.thoughtcrime.securesms.transport.RetryLaterException; -import org.thoughtcrime.securesms.util.Util; import java.io.IOException; import java.util.Collections; @@ -96,8 +95,8 @@ final class GroupsV1MigrationRepository { group = group.fresh(); List ineligible = Stream.of(group.getParticipants()) - .filter(r -> !r.hasUuid() || - r.getGroupsV2Capability() != Recipient.Capability.SUPPORTED || + .filter(r -> !r.hasAci() || + r.getGroupsV2Capability() != Recipient.Capability.SUPPORTED || r.getGroupsV1MigrationCapability() != Recipient.Capability.SUPPORTED || r.getRegistered() != RecipientDatabase.RegisteredState.REGISTERED) .toList(); diff --git a/app/src/main/java/org/thoughtcrime/securesms/groups/v2/GroupCandidateHelper.java b/app/src/main/java/org/thoughtcrime/securesms/groups/v2/GroupCandidateHelper.java index 4118771c51..cecb718505 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/groups/v2/GroupCandidateHelper.java +++ b/app/src/main/java/org/thoughtcrime/securesms/groups/v2/GroupCandidateHelper.java @@ -17,6 +17,7 @@ import org.thoughtcrime.securesms.recipients.RecipientId; import org.whispersystems.libsignal.util.guava.Optional; import org.whispersystems.signalservice.api.SignalServiceAccountManager; import org.whispersystems.signalservice.api.groupsv2.GroupCandidate; +import org.whispersystems.signalservice.api.push.ACI; import java.io.IOException; import java.util.Collection; @@ -47,13 +48,13 @@ public final class GroupCandidateHelper { { final Recipient recipient = Recipient.resolved(recipientId); - UUID uuid = recipient.getUuid().orNull(); - if (uuid == null) { + ACI aci = recipient.getAci().orNull(); + if (aci == null) { throw new AssertionError("Non UUID members should have need detected by now"); } Optional profileKeyCredential = Optional.fromNullable(recipient.getProfileKeyCredential()); - GroupCandidate candidate = new GroupCandidate(uuid, profileKeyCredential); + GroupCandidate candidate = new GroupCandidate(aci.uuid(), profileKeyCredential); if (!candidate.hasProfileKeyCredential()) { ProfileKey profileKey = ProfileKeyUtil.profileKeyOrNull(recipient.getProfileKey()); @@ -61,7 +62,7 @@ public final class GroupCandidateHelper { if (profileKey != null) { Log.i(TAG, String.format("No profile key credential on recipient %s, fetching", recipient.getId())); - Optional profileKeyCredentialOptional = signalServiceAccountManager.resolveProfileKeyCredential(uuid, profileKey, Locale.getDefault()); + Optional profileKeyCredentialOptional = signalServiceAccountManager.resolveProfileKeyCredential(aci, profileKey, Locale.getDefault()); if (profileKeyCredentialOptional.isPresent()) { boolean updatedProfileKey = recipientDatabase.setProfileKeyCredential(recipient.getId(), profileKey, profileKeyCredentialOptional.get()); diff --git a/app/src/main/java/org/thoughtcrime/securesms/groups/v2/ProfileKeySet.java b/app/src/main/java/org/thoughtcrime/securesms/groups/v2/ProfileKeySet.java index c6f33baf7d..1a80663360 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/groups/v2/ProfileKeySet.java +++ b/app/src/main/java/org/thoughtcrime/securesms/groups/v2/ProfileKeySet.java @@ -12,6 +12,7 @@ import org.signal.storageservice.protos.groups.local.DecryptedMember; import org.signal.storageservice.protos.groups.local.DecryptedRequestingMember; import org.signal.zkgroup.InvalidInputException; import org.signal.zkgroup.profiles.ProfileKey; +import org.whispersystems.signalservice.api.push.ACI; import org.whispersystems.signalservice.api.util.UuidUtil; import java.util.LinkedHashMap; @@ -30,8 +31,8 @@ public final class ProfileKeySet { private static final String TAG = Log.tag(ProfileKeySet.class); - private final Map profileKeys = new LinkedHashMap<>(); - private final Map authoritativeProfileKeys = new LinkedHashMap<>(); + private final Map profileKeys = new LinkedHashMap<>(); + private final Map authoritativeProfileKeys = new LinkedHashMap<>(); /** * Add new profile keys from a group change. @@ -96,20 +97,20 @@ public final class ProfileKeySet { } if (memberUuid.equals(changeSource)) { - authoritativeProfileKeys.put(memberUuid, profileKey); - profileKeys.remove(memberUuid); + authoritativeProfileKeys.put(ACI.from(memberUuid), profileKey); + profileKeys.remove(ACI.from(memberUuid)); } else { - if (!authoritativeProfileKeys.containsKey(memberUuid)) { - profileKeys.put(memberUuid, profileKey); + if (!authoritativeProfileKeys.containsKey(ACI.from(memberUuid))) { + profileKeys.put(ACI.from(memberUuid), profileKey); } } } - public Map getProfileKeys() { + public Map getProfileKeys() { return profileKeys; } - public Map getAuthoritativeProfileKeys() { + public Map getAuthoritativeProfileKeys() { return authoritativeProfileKeys; } } diff --git a/app/src/main/java/org/thoughtcrime/securesms/groups/v2/processing/GroupsV2StateProcessor.java b/app/src/main/java/org/thoughtcrime/securesms/groups/v2/processing/GroupsV2StateProcessor.java index 5dcc26fbce..a7cdf30b37 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/groups/v2/processing/GroupsV2StateProcessor.java +++ b/app/src/main/java/org/thoughtcrime/securesms/groups/v2/processing/GroupsV2StateProcessor.java @@ -49,6 +49,7 @@ import org.whispersystems.signalservice.api.groupsv2.DecryptedGroupUtil; import org.whispersystems.signalservice.api.groupsv2.GroupsV2Api; import org.whispersystems.signalservice.api.groupsv2.InvalidGroupStateException; import org.whispersystems.signalservice.api.groupsv2.NotAbleToApplyGroupV2ChangeException; +import org.whispersystems.signalservice.api.push.ACI; import org.whispersystems.signalservice.api.util.UuidUtil; import org.whispersystems.signalservice.internal.push.exceptions.GroupNotFoundException; import org.whispersystems.signalservice.internal.push.exceptions.NotInGroupException; @@ -206,7 +207,7 @@ public final class GroupsV2StateProcessor { } if (inputGroupState == null) { - if (localState != null && DecryptedGroupUtil.isPendingOrRequesting(localState, Recipient.self().getUuid().get())) { + if (localState != null && DecryptedGroupUtil.isPendingOrRequesting(localState, Recipient.self().requireAci().uuid())) { Log.w(TAG, "Unable to query server for group " + groupId + " server says we're not in group, but we think we are a pending or requesting member"); } else { Log.w(TAG, "Unable to query server for group " + groupId + " server says we're not in group, inserting leave message"); @@ -250,7 +251,7 @@ public final class GroupsV2StateProcessor { throws IOException, GroupNotAMemberException, GroupDoesNotExistException { try { - return groupsV2Api.getGroup(groupSecretParams, groupsV2Authorization.getAuthorizationForToday(Recipient.self().requireUuid(), groupSecretParams)); + return groupsV2Api.getGroup(groupSecretParams, groupsV2Authorization.getAuthorizationForToday(Recipient.self().requireAci(), groupSecretParams)); } catch (GroupNotFoundException e) { throw new GroupDoesNotExistException(e); } catch (NotInGroupException e) { @@ -265,7 +266,7 @@ public final class GroupsV2StateProcessor { throws IOException, GroupNotAMemberException, GroupDoesNotExistException { try { - return groupsV2Api.getGroupHistory(groupSecretParams, revision, groupsV2Authorization.getAuthorizationForToday(Recipient.self().requireUuid(), groupSecretParams)) + return groupsV2Api.getGroupHistory(groupSecretParams, revision, groupsV2Authorization.getAuthorizationForToday(Recipient.self().requireAci(), groupSecretParams)) .get(0) .getGroup() .orNull(); @@ -285,7 +286,7 @@ public final class GroupsV2StateProcessor { } Recipient groupRecipient = Recipient.externalGroupExact(context, groupId); - UUID selfUuid = Recipient.self().getUuid().get(); + UUID selfUuid = Recipient.self().requireAci().uuid(); DecryptedGroup decryptedGroup = groupDatabase.requireGroup(groupId) .requireV2GroupProperties() .getDecryptedGroup(); @@ -359,7 +360,7 @@ public final class GroupsV2StateProcessor { @NonNull DecryptedGroup newLocalState) { if (inputGroupState.getLocalState() != null) { - boolean wasAMemberAlready = DecryptedGroupUtil.findMemberByUuid(inputGroupState.getLocalState().getMembersList(), Recipient.self().getUuid().get()).isPresent(); + boolean wasAMemberAlready = DecryptedGroupUtil.findMemberByUuid(inputGroupState.getLocalState().getMembersList(), Recipient.self().requireAci().uuid()).isPresent(); if (wasAMemberAlready) { Log.i(TAG, "Skipping profile sharing detection as was already a full member before update"); @@ -367,7 +368,7 @@ public final class GroupsV2StateProcessor { } } - Optional selfAsMemberOptional = DecryptedGroupUtil.findMemberByUuid(newLocalState.getMembersList(), Recipient.self().getUuid().get()); + Optional selfAsMemberOptional = DecryptedGroupUtil.findMemberByUuid(newLocalState.getMembersList(), Recipient.self().requireAci().uuid()); if (selfAsMemberOptional.isPresent()) { DecryptedMember selfAsMember = selfAsMemberOptional.get(); @@ -378,7 +379,7 @@ public final class GroupsV2StateProcessor { .filter(c -> c != null && c.getRevision() == revisionJoinedAt) .findFirst() .map(c -> Optional.fromNullable(UuidUtil.fromByteStringOrNull(c.getEditor())) - .transform(a -> Recipient.externalPush(context, UuidUtil.fromByteStringOrNull(c.getEditor()), null, false))) + .transform(a -> Recipient.externalPush(context, ACI.fromByteStringOrNull(c.getEditor()), null, false))) .orElse(Optional.absent()); if (addedByOptional.isPresent()) { @@ -446,33 +447,33 @@ public final class GroupsV2StateProcessor { private @NonNull GlobalGroupState queryServer(@Nullable DecryptedGroup localState, boolean latestOnly) throws IOException, GroupNotAMemberException { - UUID selfUuid = Recipient.self().getUuid().get(); + ACI selfAci = Recipient.self().requireAci(); DecryptedGroup latestServerGroup; List history; try { - latestServerGroup = groupsV2Api.getGroup(groupSecretParams, groupsV2Authorization.getAuthorizationForToday(selfUuid, groupSecretParams)); + latestServerGroup = groupsV2Api.getGroup(groupSecretParams, groupsV2Authorization.getAuthorizationForToday(selfAci, groupSecretParams)); } catch (NotInGroupException | GroupNotFoundException e) { throw new GroupNotAMemberException(e); } catch (VerificationFailedException | InvalidGroupStateException e) { throw new IOException(e); } - if (latestOnly || !GroupProtoUtil.isMember(selfUuid, latestServerGroup.getMembersList())) { + if (latestOnly || !GroupProtoUtil.isMember(selfAci.uuid(), latestServerGroup.getMembersList())) { history = Collections.singletonList(new ServerGroupLogEntry(latestServerGroup, null)); } else { - int revisionWeWereAdded = GroupProtoUtil.findRevisionWeWereAdded(latestServerGroup, selfUuid); + int revisionWeWereAdded = GroupProtoUtil.findRevisionWeWereAdded(latestServerGroup, selfAci.uuid()); int logsNeededFrom = localState != null ? Math.max(localState.getRevision(), revisionWeWereAdded) : revisionWeWereAdded; - history = getFullMemberHistory(selfUuid, logsNeededFrom); + history = getFullMemberHistory(selfAci, logsNeededFrom); } return new GlobalGroupState(localState, history); } - private List getFullMemberHistory(@NonNull UUID selfUuid, int logsNeededFromRevision) throws IOException { + private List getFullMemberHistory(@NonNull ACI selfAci, int logsNeededFromRevision) throws IOException { try { - Collection groupStatesFromRevision = groupsV2Api.getGroupHistory(groupSecretParams, logsNeededFromRevision, groupsV2Authorization.getAuthorizationForToday(selfUuid, groupSecretParams)); + Collection groupStatesFromRevision = groupsV2Api.getGroupHistory(groupSecretParams, logsNeededFromRevision, groupsV2Authorization.getAuthorizationForToday(selfAci, groupSecretParams)); ArrayList history = new ArrayList<>(groupStatesFromRevision.size()); boolean ignoreServerChanges = SignalStore.internalValues().gv2IgnoreServerChanges(); @@ -496,9 +497,9 @@ public final class GroupsV2StateProcessor { } private void storeMessage(@NonNull DecryptedGroupV2Context decryptedGroupV2Context, long timestamp) { - Optional editor = getEditor(decryptedGroupV2Context); + Optional editor = getEditor(decryptedGroupV2Context).transform(ACI::from); - boolean outgoing = !editor.isPresent() || Recipient.self().requireUuid().equals(editor.get()); + boolean outgoing = !editor.isPresent() || Recipient.self().requireAci().equals(editor.get()); if (outgoing) { try { @@ -536,7 +537,7 @@ public final class GroupsV2StateProcessor { if (changeEditor.isPresent()) { return changeEditor; } else { - Optional pendingByUuid = DecryptedGroupUtil.findPendingByUuid(decryptedGroupV2Context.getGroupState().getPendingMembersList(), Recipient.self().requireUuid()); + Optional pendingByUuid = DecryptedGroupUtil.findPendingByUuid(decryptedGroupV2Context.getGroupState().getPendingMembersList(), Recipient.self().requireAci().uuid()); if (pendingByUuid.isPresent()) { return Optional.fromNullable(UuidUtil.fromByteStringOrNull(pendingByUuid.get().getAddedByUuid())); } diff --git a/app/src/main/java/org/thoughtcrime/securesms/jobs/GroupV1MigrationJob.java b/app/src/main/java/org/thoughtcrime/securesms/jobs/GroupV1MigrationJob.java index 836872e955..2a4b51fad4 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/jobs/GroupV1MigrationJob.java +++ b/app/src/main/java/org/thoughtcrime/securesms/jobs/GroupV1MigrationJob.java @@ -21,7 +21,6 @@ import org.thoughtcrime.securesms.keyvalue.SignalStore; import org.thoughtcrime.securesms.recipients.Recipient; import org.thoughtcrime.securesms.recipients.RecipientId; import org.thoughtcrime.securesms.transport.RetryLaterException; -import org.thoughtcrime.securesms.util.FeatureFlags; import org.thoughtcrime.securesms.util.TextSecurePreferences; import org.whispersystems.signalservice.api.groupsv2.NoCredentialForRedemptionTimeException; import org.whispersystems.signalservice.api.push.exceptions.PushNetworkException; @@ -71,7 +70,7 @@ public class GroupV1MigrationJob extends BaseJob { public static void enqueueRoutineMigrationsIfNecessary(@NonNull Application application) { if (!SignalStore.registrationValues().isRegistrationComplete() || !TextSecurePreferences.isPushRegistered(application) || - TextSecurePreferences.getLocalUuid(application) == null) + TextSecurePreferences.getLocalAci(application) == null) { Log.i(TAG, "Registration not complete. Skipping."); return; diff --git a/app/src/main/java/org/thoughtcrime/securesms/jobs/MmsDownloadJob.java b/app/src/main/java/org/thoughtcrime/securesms/jobs/MmsDownloadJob.java index 6518d21f9d..360436b755 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/jobs/MmsDownloadJob.java +++ b/app/src/main/java/org/thoughtcrime/securesms/jobs/MmsDownloadJob.java @@ -105,7 +105,7 @@ public class MmsDownloadJob extends BaseJob { @Override public void onRun() { - if (TextSecurePreferences.getLocalUuid(context) == null && TextSecurePreferences.getLocalNumber(context) == null) { + if (TextSecurePreferences.getLocalAci(context) == null && TextSecurePreferences.getLocalNumber(context) == null) { throw new NotReadyException(); } diff --git a/app/src/main/java/org/thoughtcrime/securesms/jobs/MultiDeviceBlockedUpdateJob.java b/app/src/main/java/org/thoughtcrime/securesms/jobs/MultiDeviceBlockedUpdateJob.java index 18e26b826b..a3b4738f5c 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/jobs/MultiDeviceBlockedUpdateJob.java +++ b/app/src/main/java/org/thoughtcrime/securesms/jobs/MultiDeviceBlockedUpdateJob.java @@ -82,7 +82,7 @@ public class MultiDeviceBlockedUpdateJob extends BaseJob { while ((recipient = reader.getNext()) != null) { if (recipient.isPushGroup()) { blockedGroups.add(recipient.requireGroupId().getDecodedId()); - } else if (recipient.isMaybeRegistered() && (recipient.hasUuid() || recipient.hasE164())) { + } else if (recipient.isMaybeRegistered() && (recipient.hasAci() || recipient.hasE164())) { blockedIndividuals.add(RecipientUtil.toSignalServiceAddress(context, recipient)); } } diff --git a/app/src/main/java/org/thoughtcrime/securesms/jobs/MultiDeviceOutgoingPaymentSyncJob.java b/app/src/main/java/org/thoughtcrime/securesms/jobs/MultiDeviceOutgoingPaymentSyncJob.java index f943768235..4b2f498b49 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/jobs/MultiDeviceOutgoingPaymentSyncJob.java +++ b/app/src/main/java/org/thoughtcrime/securesms/jobs/MultiDeviceOutgoingPaymentSyncJob.java @@ -19,6 +19,7 @@ import org.thoughtcrime.securesms.util.TextSecurePreferences; import org.whispersystems.libsignal.util.guava.Optional; import org.whispersystems.signalservice.api.messages.multidevice.OutgoingPaymentMessage; import org.whispersystems.signalservice.api.messages.multidevice.SignalServiceSyncMessage; +import org.whispersystems.signalservice.api.push.SignalServiceAddress; import org.whispersystems.signalservice.api.push.exceptions.PushNetworkException; import org.whispersystems.signalservice.api.push.exceptions.ServerRejectedException; @@ -88,9 +89,9 @@ public final class MultiDeviceOutgoingPaymentSyncJob extends BaseJob { boolean defrag = payment.isDefrag(); - Optional uuid; + Optional uuid; if (!defrag && payment.getPayee().hasRecipientId()) { - uuid = Optional.of(Recipient.resolved(payment.getPayee().requireRecipientId()).requireUuid()); + uuid = Optional.of(new SignalServiceAddress(Recipient.resolved(payment.getPayee().requireRecipientId()).requireAci())); } else { uuid = Optional.absent(); } diff --git a/app/src/main/java/org/thoughtcrime/securesms/jobs/PushGroupSilentUpdateSendJob.java b/app/src/main/java/org/thoughtcrime/securesms/jobs/PushGroupSilentUpdateSendJob.java index 8a3eff2807..50b2711120 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/jobs/PushGroupSilentUpdateSendJob.java +++ b/app/src/main/java/org/thoughtcrime/securesms/jobs/PushGroupSilentUpdateSendJob.java @@ -30,6 +30,7 @@ import org.whispersystems.signalservice.api.groupsv2.DecryptedGroupUtil; import org.whispersystems.signalservice.api.messages.SendMessageResult; import org.whispersystems.signalservice.api.messages.SignalServiceDataMessage; import org.whispersystems.signalservice.api.messages.SignalServiceGroupV2; +import org.whispersystems.signalservice.api.push.ACI; import org.whispersystems.signalservice.api.push.exceptions.ServerRejectedException; import org.whispersystems.signalservice.api.util.UuidUtil; import org.whispersystems.signalservice.internal.push.SignalServiceProtos; @@ -73,8 +74,8 @@ public final class PushGroupSilentUpdateSendJob extends BaseJob { Set recipients = Stream.concat(Stream.of(memberUuids), Stream.of(pendingUuids)) .filter(uuid -> !UuidUtil.UNKNOWN_UUID.equals(uuid)) - .filter(uuid -> !Recipient.self().getUuid().get().equals(uuid)) - .map(uuid -> Recipient.externalPush(context, uuid, null, false)) + .filter(uuid -> !Recipient.self().requireAci().uuid().equals(uuid)) + .map(uuid -> Recipient.externalPush(context, ACI.from(uuid), null, false)) .filter(recipient -> recipient.getRegistered() != RecipientDatabase.RegisteredState.NOT_REGISTERED) .map(Recipient::getId) .collect(Collectors.toSet()); diff --git a/app/src/main/java/org/thoughtcrime/securesms/jobs/PushMediaSendJob.java b/app/src/main/java/org/thoughtcrime/securesms/jobs/PushMediaSendJob.java index 135459f457..0cb91fb911 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/jobs/PushMediaSendJob.java +++ b/app/src/main/java/org/thoughtcrime/securesms/jobs/PushMediaSendJob.java @@ -226,7 +226,7 @@ public class PushMediaSendJob extends PushSendJob { .asExpirationUpdate(message.isExpirationUpdate()) .build(); - if (Util.equals(TextSecurePreferences.getLocalUuid(context), address.getUuid())) { + if (Util.equals(TextSecurePreferences.getLocalAci(context), address.getAci())) { Optional syncAccess = UnidentifiedAccessUtil.getAccessForSync(context); SignalServiceSyncMessage syncMessage = buildSelfSendSyncMessage(context, mediaMessage, syncAccess); diff --git a/app/src/main/java/org/thoughtcrime/securesms/jobs/PushSendJob.java b/app/src/main/java/org/thoughtcrime/securesms/jobs/PushSendJob.java index 2cc991e170..a9cce96453 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/jobs/PushSendJob.java +++ b/app/src/main/java/org/thoughtcrime/securesms/jobs/PushSendJob.java @@ -13,7 +13,6 @@ import com.annimon.stream.Stream; import org.greenrobot.eventbus.EventBus; import org.greenrobot.eventbus.Subscribe; import org.greenrobot.eventbus.ThreadMode; -import org.signal.core.util.ThreadUtil; import org.signal.core.util.logging.Log; import org.signal.libsignal.metadata.certificate.InvalidCertificateException; import org.signal.libsignal.metadata.certificate.SenderCertificate; @@ -43,7 +42,6 @@ import org.thoughtcrime.securesms.net.NotPushRegisteredException; import org.thoughtcrime.securesms.recipients.Recipient; import org.thoughtcrime.securesms.recipients.RecipientId; import org.thoughtcrime.securesms.recipients.RecipientUtil; -import org.thoughtcrime.securesms.registration.PushChallengeRequest; import org.thoughtcrime.securesms.transport.RetryLaterException; import org.thoughtcrime.securesms.util.Base64; import org.thoughtcrime.securesms.util.BitmapDecodingException; @@ -51,11 +49,9 @@ import org.thoughtcrime.securesms.util.BitmapUtil; import org.thoughtcrime.securesms.util.FeatureFlags; import org.thoughtcrime.securesms.util.Hex; import org.thoughtcrime.securesms.util.MediaUtil; -import org.thoughtcrime.securesms.util.SignalLocalMetrics; import org.thoughtcrime.securesms.util.TextSecurePreferences; import org.thoughtcrime.securesms.util.Util; import org.whispersystems.libsignal.util.guava.Optional; -import org.whispersystems.signalservice.api.SignalServiceAccountManager; import org.whispersystems.signalservice.api.crypto.UnidentifiedAccessPair; import org.whispersystems.signalservice.api.messages.SignalServiceAttachment; import org.whispersystems.signalservice.api.messages.SignalServiceAttachmentPointer; @@ -68,10 +64,7 @@ import org.whispersystems.signalservice.api.messages.shared.SharedContact; import org.whispersystems.signalservice.api.push.SignalServiceAddress; import org.whispersystems.signalservice.api.push.exceptions.NonSuccessfulResponseCodeException; import org.whispersystems.signalservice.api.push.exceptions.ProofRequiredException; -import org.whispersystems.signalservice.api.push.exceptions.PushNetworkException; import org.whispersystems.signalservice.api.push.exceptions.ServerRejectedException; -import org.whispersystems.signalservice.api.push.exceptions.UnregisteredUserException; -import org.whispersystems.signalservice.internal.push.ProofRequiredResponse; import java.io.ByteArrayInputStream; import java.io.IOException; @@ -416,7 +409,7 @@ public abstract class PushSendJob extends SendJob { List getMentionsFor(@NonNull List mentions) { return Stream.of(mentions) - .map(m -> new SignalServiceDataMessage.Mention(Recipient.resolved(m.getRecipientId()).requireUuid(), m.getStart(), m.getLength())) + .map(m -> new SignalServiceDataMessage.Mention(Recipient.resolved(m.getRecipientId()).requireAci(), m.getStart(), m.getLength())) .toList(); } @@ -454,7 +447,7 @@ public abstract class PushSendJob extends SendJob { } protected SignalServiceSyncMessage buildSelfSendSyncMessage(@NonNull Context context, @NonNull SignalServiceDataMessage message, Optional syncAccess) { - SignalServiceAddress localAddress = new SignalServiceAddress(TextSecurePreferences.getLocalUuid(context), TextSecurePreferences.getLocalNumber(context)); + SignalServiceAddress localAddress = new SignalServiceAddress(TextSecurePreferences.getLocalAci(context), TextSecurePreferences.getLocalNumber(context)); SentTranscriptMessage transcript = new SentTranscriptMessage(Optional.of(localAddress), message.getTimestamp(), message, diff --git a/app/src/main/java/org/thoughtcrime/securesms/jobs/PushTextSendJob.java b/app/src/main/java/org/thoughtcrime/securesms/jobs/PushTextSendJob.java index f8ffa750b9..508ace0533 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/jobs/PushTextSendJob.java +++ b/app/src/main/java/org/thoughtcrime/securesms/jobs/PushTextSendJob.java @@ -188,7 +188,7 @@ public class PushTextSendJob extends PushSendJob { .asEndSessionMessage(message.isEndSession()) .build(); - if (Util.equals(TextSecurePreferences.getLocalUuid(context), address.getUuid())) { + if (Util.equals(TextSecurePreferences.getLocalAci(context), address.getAci())) { Optional syncAccess = UnidentifiedAccessUtil.getAccessForSync(context); SignalServiceSyncMessage syncMessage = buildSelfSendSyncMessage(context, textSecureMessage, syncAccess); diff --git a/app/src/main/java/org/thoughtcrime/securesms/jobs/RetrieveProfileJob.java b/app/src/main/java/org/thoughtcrime/securesms/jobs/RetrieveProfileJob.java index 2af90a0e43..7d141f5af2 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/jobs/RetrieveProfileJob.java +++ b/app/src/main/java/org/thoughtcrime/securesms/jobs/RetrieveProfileJob.java @@ -2,7 +2,6 @@ package org.thoughtcrime.securesms.jobs; import android.app.Application; import android.content.Context; -import android.net.Uri; import android.text.TextUtils; import androidx.annotation.NonNull; @@ -16,9 +15,7 @@ import org.signal.core.util.concurrent.SignalExecutors; import org.signal.core.util.logging.Log; import org.signal.zkgroup.profiles.ProfileKey; import org.signal.zkgroup.profiles.ProfileKeyCredential; -import org.thoughtcrime.securesms.BuildConfig; import org.thoughtcrime.securesms.badges.Badges; -import org.thoughtcrime.securesms.badges.models.Badge; import org.thoughtcrime.securesms.crypto.ProfileKeyUtil; import org.thoughtcrime.securesms.database.DatabaseFactory; import org.thoughtcrime.securesms.database.GroupDatabase; @@ -38,7 +35,6 @@ import org.thoughtcrime.securesms.transport.RetryLaterException; import org.thoughtcrime.securesms.util.Base64; import org.thoughtcrime.securesms.util.IdentityUtil; import org.thoughtcrime.securesms.util.ProfileUtil; -import org.thoughtcrime.securesms.util.ScreenDensity; import org.thoughtcrime.securesms.util.SetUtil; import org.thoughtcrime.securesms.util.Stopwatch; import org.thoughtcrime.securesms.util.TextSecurePreferences; @@ -51,6 +47,7 @@ import org.whispersystems.signalservice.api.crypto.InvalidCiphertextException; import org.whispersystems.signalservice.api.crypto.ProfileCipher; import org.whispersystems.signalservice.api.profiles.ProfileAndCredential; import org.whispersystems.signalservice.api.profiles.SignalServiceProfile; +import org.whispersystems.signalservice.api.push.ACI; import org.whispersystems.signalservice.api.services.ProfileService; import org.whispersystems.signalservice.internal.ServiceResponse; @@ -62,7 +59,6 @@ import java.util.List; import java.util.Locale; import java.util.Map; import java.util.Set; -import java.util.UUID; import java.util.concurrent.TimeUnit; import io.reactivex.rxjava3.core.Observable; @@ -175,7 +171,7 @@ public class RetrieveProfileJob extends BaseJob { public static void enqueueRoutineFetchIfNecessary(Application application) { if (!SignalStore.registrationValues().isRegistrationComplete() || !TextSecurePreferences.isPushRegistered(application) || - TextSecurePreferences.getLocalUuid(application) == null) + TextSecurePreferences.getLocalAci(application) == null) { Log.i(TAG, "Registration not complete. Skipping."); return; @@ -293,11 +289,11 @@ public class RetrieveProfileJob extends BaseJob { Set success = SetUtil.difference(recipientIds, operationState.retries); recipientDatabase.markProfilesFetched(success, System.currentTimeMillis()); - Map newlyRegistered = Stream.of(operationState.profiles) - .map(Pair::first) - .filterNot(Recipient::isRegistered) - .collect(Collectors.toMap(Recipient::getId, - r -> r.getUuid().transform(UUID::toString).orNull())); + Map newlyRegistered = Stream.of(operationState.profiles) + .map(Pair::first) + .filterNot(Recipient::isRegistered) + .collect(Collectors.toMap(Recipient::getId, + r -> r.getAci().orNull())); if (operationState.unregistered.size() > 0 || newlyRegistered.size() > 0) { Log.i(TAG, "Marking " + newlyRegistered.size() + " users as registered and " + operationState.unregistered.size() + " users as unregistered."); diff --git a/app/src/main/java/org/thoughtcrime/securesms/jobs/SmsReceiveJob.java b/app/src/main/java/org/thoughtcrime/securesms/jobs/SmsReceiveJob.java index 82249ae0fd..8abe607a45 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/jobs/SmsReceiveJob.java +++ b/app/src/main/java/org/thoughtcrime/securesms/jobs/SmsReceiveJob.java @@ -89,7 +89,7 @@ public class SmsReceiveJob extends BaseJob { public void onRun() throws MigrationPendingException, RetryLaterException { Optional message = assembleMessageFragments(pdus, subscriptionId); - if (TextSecurePreferences.getLocalUuid(context) == null && TextSecurePreferences.getLocalNumber(context) == null) { + if (TextSecurePreferences.getLocalAci(context) == null && TextSecurePreferences.getLocalNumber(context) == null) { Log.i(TAG, "Received an SMS before we're registered..."); if (message.isPresent()) { diff --git a/app/src/main/java/org/thoughtcrime/securesms/logsubmit/LogSectionCapabilities.java b/app/src/main/java/org/thoughtcrime/securesms/logsubmit/LogSectionCapabilities.java index 47d7e2fb55..2a027e9fe2 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/logsubmit/LogSectionCapabilities.java +++ b/app/src/main/java/org/thoughtcrime/securesms/logsubmit/LogSectionCapabilities.java @@ -22,7 +22,7 @@ public final class LogSectionCapabilities implements LogSection { return "Unregistered"; } - if (TextSecurePreferences.getLocalNumber(context) == null || TextSecurePreferences.getLocalUuid(context) == null) { + if (TextSecurePreferences.getLocalNumber(context) == null || TextSecurePreferences.getLocalAci(context) == null) { return "Self not yet available!"; } diff --git a/app/src/main/java/org/thoughtcrime/securesms/logsubmit/LogSectionKeyPreferences.java b/app/src/main/java/org/thoughtcrime/securesms/logsubmit/LogSectionKeyPreferences.java index eac551c920..de531f7c6f 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/logsubmit/LogSectionKeyPreferences.java +++ b/app/src/main/java/org/thoughtcrime/securesms/logsubmit/LogSectionKeyPreferences.java @@ -29,7 +29,7 @@ final class LogSectionKeyPreferences implements LogSection { .append("Client Deprecated : ").append(SignalStore.misc().isClientDeprecated()).append("\n") .append("Push Registered : ").append(TextSecurePreferences.isPushRegistered(context)).append("\n") .append("Unauthorized Received: ").append(TextSecurePreferences.isUnauthorizedRecieved(context)).append("\n") - .append("self.isRegistered() : ").append(TextSecurePreferences.getLocalUuid(context) == null ? "false" : Recipient.self().isRegistered()).append("\n") + .append("self.isRegistered() : ").append(TextSecurePreferences.getLocalAci(context) == null ? "false" : Recipient.self().isRegistered()).append("\n") .append("Thread Trimming : ").append(getThreadTrimmingString()).append("\n"); } diff --git a/app/src/main/java/org/thoughtcrime/securesms/logsubmit/LogSectionSystemInfo.java b/app/src/main/java/org/thoughtcrime/securesms/logsubmit/LogSectionSystemInfo.java index 7bf7022879..9a2d679717 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/logsubmit/LogSectionSystemInfo.java +++ b/app/src/main/java/org/thoughtcrime/securesms/logsubmit/LogSectionSystemInfo.java @@ -15,7 +15,6 @@ import com.google.android.gms.common.GoogleApiAvailability; import org.thoughtcrime.securesms.BuildConfig; import org.thoughtcrime.securesms.emoji.EmojiFiles; -import org.thoughtcrime.securesms.emoji.EmojiSource; import org.thoughtcrime.securesms.keyvalue.SignalStore; import org.thoughtcrime.securesms.recipients.Recipient; import org.thoughtcrime.securesms.util.AppSignatureUtil; @@ -27,12 +26,11 @@ import org.thoughtcrime.securesms.util.ServiceUtil; import org.thoughtcrime.securesms.util.TextSecurePreferences; import org.thoughtcrime.securesms.util.Util; import org.thoughtcrime.securesms.util.VersionTracker; +import org.whispersystems.signalservice.api.push.ACI; import java.util.Arrays; -import java.util.LinkedHashMap; import java.util.LinkedList; import java.util.Locale; -import java.util.Map; import java.util.UUID; public class LogSectionSystemInfo implements LogSection { @@ -64,7 +62,7 @@ public class LogSectionSystemInfo implements LogSection { builder.append("MemInfo : ").append(getMemoryInfo(context)).append("\n"); builder.append("OS Host : ").append(Build.HOST).append("\n"); builder.append("RecipientId : ").append(SignalStore.registrationValues().isRegistrationComplete() ? Recipient.self().getId() : "N/A").append("\n"); - builder.append("UUID : ").append(getCensoredUuid(context)).append("\n"); + builder.append("ACI : ").append(getCensoredAci(context)).append("\n"); builder.append("Censored : ").append(CensorshipUtil.isCensored(context)).append("\n"); builder.append("Play Services : ").append(getPlayServicesString(context)).append("\n"); builder.append("FCM : ").append(!TextSecurePreferences.isFcmDisabled(context)).append("\n"); @@ -166,12 +164,12 @@ public class LogSectionSystemInfo implements LogSection { } } - private static String getCensoredUuid(@NonNull Context context) { - UUID uuid = TextSecurePreferences.getLocalUuid(context); + private static String getCensoredAci(@NonNull Context context) { + ACI aci = TextSecurePreferences.getLocalAci(context); - if (uuid != null) { - String uuidString = uuid.toString(); - String lastTwo = uuidString.substring(uuidString.length() - 2); + if (aci != null) { + String aciString = aci.toString(); + String lastTwo = aciString.substring(aciString.length() - 2); return "********-****-****-****-**********" + lastTwo; } else { diff --git a/app/src/main/java/org/thoughtcrime/securesms/messages/GroupSendUtil.java b/app/src/main/java/org/thoughtcrime/securesms/messages/GroupSendUtil.java index 9c8817ea19..78c1b02779 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/messages/GroupSendUtil.java +++ b/app/src/main/java/org/thoughtcrime/securesms/messages/GroupSendUtil.java @@ -174,9 +174,9 @@ public final class GroupSendUtil { boolean validMembership = groupRecord.isPresent() && groupRecord.get().getMembers().contains(recipient.getId()); if (recipient.getSenderKeyCapability() == Recipient.Capability.SUPPORTED && - recipient.hasUuid() && - access.isPresent() && - access.get().getTargetUnidentifiedAccess().isPresent() && + recipient.hasAci() && + access.isPresent() && + access.get().getTargetUnidentifiedAccess().isPresent() && validMembership) { senderKeyTargets.add(recipient); @@ -312,8 +312,8 @@ public final class GroupSendUtil { Log.w(TAG, "There are " + unregisteredTargets.size() + " unregistered targets. Including failure results."); List unregisteredResults = unregisteredTargets.stream() - .filter(Recipient::hasUuid) - .map(t -> SendMessageResult.unregisteredFailure(new SignalServiceAddress(t.requireUuid(), t.getE164().orNull()))) + .filter(Recipient::hasAci) + .map(t -> SendMessageResult.unregisteredFailure(new SignalServiceAddress(t.requireAci(), t.getE164().orNull()))) .collect(Collectors.toList()); if (unregisteredResults.size() < unregisteredTargets.size()) { diff --git a/app/src/main/java/org/thoughtcrime/securesms/messages/MessageContentProcessor.java b/app/src/main/java/org/thoughtcrime/securesms/messages/MessageContentProcessor.java index 159d5c0c76..055d299168 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/messages/MessageContentProcessor.java +++ b/app/src/main/java/org/thoughtcrime/securesms/messages/MessageContentProcessor.java @@ -26,7 +26,6 @@ import org.thoughtcrime.securesms.contactshare.ContactModelMapper; import org.thoughtcrime.securesms.crypto.ProfileKeyUtil; import org.thoughtcrime.securesms.crypto.SecurityEvent; import org.thoughtcrime.securesms.crypto.SessionUtil; -import org.thoughtcrime.securesms.crypto.storage.TextSecureSessionStore; import org.thoughtcrime.securesms.database.AttachmentDatabase; import org.thoughtcrime.securesms.database.DatabaseFactory; import org.thoughtcrime.securesms.database.GroupDatabase; @@ -83,7 +82,6 @@ import org.thoughtcrime.securesms.jobs.RetrieveProfileJob; import org.thoughtcrime.securesms.jobs.SendDeliveryReceiptJob; import org.thoughtcrime.securesms.jobs.SenderKeyDistributionSendJob; import org.thoughtcrime.securesms.jobs.StickerPackDownloadJob; -import org.thoughtcrime.securesms.jobs.ThreadUpdateJob; import org.thoughtcrime.securesms.jobs.TrimThreadJob; import org.thoughtcrime.securesms.keyvalue.SignalStore; import org.thoughtcrime.securesms.linkpreview.LinkPreview; @@ -123,7 +121,6 @@ import org.thoughtcrime.securesms.util.TextSecurePreferences; import org.thoughtcrime.securesms.util.Util; import org.whispersystems.libsignal.SignalProtocolAddress; import org.whispersystems.libsignal.protocol.DecryptionErrorMessage; -import org.whispersystems.libsignal.state.SessionStore; import org.whispersystems.libsignal.util.Pair; import org.whispersystems.libsignal.util.guava.Optional; import org.whispersystems.signalservice.api.messages.SignalServiceAttachment; @@ -643,7 +640,7 @@ public final class MessageContentProcessor { } ApplicationDependencies.getSignalCallManager() - .receivedOpaqueMessage(new WebRtcData.OpaqueMessageMetadata(senderRecipient.requireUuid(), + .receivedOpaqueMessage(new WebRtcData.OpaqueMessageMetadata(senderRecipient.requireAci().uuid(), message.getOpaque(), content.getSenderDevice(), messageAgeSeconds)); @@ -1021,7 +1018,7 @@ public final class MessageContentProcessor { private void handleSynchronizeOutgoingPayment(@NonNull SignalServiceContent content, @NonNull OutgoingPaymentMessage outgoingPaymentMessage) { RecipientId recipientId = outgoingPaymentMessage.getRecipient() - .transform(uuid -> RecipientId.from(uuid, null)) + .transform(RecipientId::from) .orNull(); long timestamp = outgoingPaymentMessage.getBlockTimestamp(); if (timestamp == 0) { @@ -1811,7 +1808,7 @@ public final class MessageContentProcessor { warn(content.getTimestamp(), "[RetryReceipt] Received a retry receipt from " + formatSender(senderRecipient, content) + " for message with timestamp " + sentTimestamp + "."); - if (!senderRecipient.hasUuid()) { + if (!senderRecipient.hasAci()) { warn(content.getTimestamp(), "[RetryReceipt] Requester " + senderRecipient.getId() + " somehow has no UUID! timestamp: " + sentTimestamp); return; } @@ -1851,7 +1848,7 @@ public final class MessageContentProcessor { GroupId.V2 groupId = threadRecipient.requireGroupId().requireV2(); DistributionId distributionId = DatabaseFactory.getGroupDatabase(context).getOrCreateDistributionId(groupId); - SignalProtocolAddress requesterAddress = new SignalProtocolAddress(requester.requireUuid().toString(), content.getSenderDevice()); + SignalProtocolAddress requesterAddress = new SignalProtocolAddress(requester.requireAci().toString(), content.getSenderDevice()); DatabaseFactory.getSenderKeySharedDatabase(context).delete(distributionId, Collections.singleton(requesterAddress)); @@ -2090,7 +2087,7 @@ public final class MessageContentProcessor { List mentions = new ArrayList<>(signalServiceMentions.size()); for (SignalServiceDataMessage.Mention mention : signalServiceMentions) { - mentions.add(new Mention(Recipient.externalPush(context, mention.getUuid(), null, false).getId(), mention.getStart(), mention.getLength())); + mentions.add(new Mention(Recipient.externalPush(context, mention.getAci(), null, false).getId(), mention.getStart(), mention.getLength())); } return mentions; @@ -2229,8 +2226,8 @@ public final class MessageContentProcessor { if (recipient.hasE164()) { unidentified |= message.isUnidentified(recipient.requireE164()); } - if (recipient.hasUuid()) { - unidentified |= message.isUnidentified(recipient.requireUuid()); + if (recipient.hasAci()) { + unidentified |= message.isUnidentified(recipient.requireAci()); } return unidentified; diff --git a/app/src/main/java/org/thoughtcrime/securesms/messages/MessageDecryptionUtil.java b/app/src/main/java/org/thoughtcrime/securesms/messages/MessageDecryptionUtil.java index 124be017b1..eb0abcfc01 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/messages/MessageDecryptionUtil.java +++ b/app/src/main/java/org/thoughtcrime/securesms/messages/MessageDecryptionUtil.java @@ -78,7 +78,7 @@ public final class MessageDecryptionUtil { */ public static @NonNull DecryptionResult decrypt(@NonNull Context context, @NonNull SignalServiceEnvelope envelope) { SignalProtocolStore axolotlStore = new SignalProtocolStoreImpl(context); - SignalServiceAddress localAddress = new SignalServiceAddress(TextSecurePreferences.getLocalUuid(context), Optional.of(TextSecurePreferences.getLocalNumber(context))); + SignalServiceAddress localAddress = new SignalServiceAddress(TextSecurePreferences.getLocalAci(context), Optional.of(TextSecurePreferences.getLocalNumber(context))); SignalServiceCipher cipher = new SignalServiceCipher(localAddress, axolotlStore, ReentrantSessionLock.INSTANCE, UnidentifiedAccessUtil.getCertificateValidator()); List jobs = new LinkedList<>(); diff --git a/app/src/main/java/org/thoughtcrime/securesms/migrations/AccountRecordMigrationJob.java b/app/src/main/java/org/thoughtcrime/securesms/migrations/AccountRecordMigrationJob.java index 700bc3fcd6..a814fdaff0 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/migrations/AccountRecordMigrationJob.java +++ b/app/src/main/java/org/thoughtcrime/securesms/migrations/AccountRecordMigrationJob.java @@ -41,7 +41,7 @@ public class AccountRecordMigrationJob extends MigrationJob { @Override public void performMigration() { - if (!TextSecurePreferences.isPushRegistered(context) || TextSecurePreferences.getLocalUuid(context) == null) { + if (!TextSecurePreferences.isPushRegistered(context) || TextSecurePreferences.getLocalAci(context) == null) { Log.w(TAG, "Not registered!"); return; } diff --git a/app/src/main/java/org/thoughtcrime/securesms/migrations/ApplyUnknownFieldsToSelfMigrationJob.java b/app/src/main/java/org/thoughtcrime/securesms/migrations/ApplyUnknownFieldsToSelfMigrationJob.java index 0c0430e77f..6d45bc28ce 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/migrations/ApplyUnknownFieldsToSelfMigrationJob.java +++ b/app/src/main/java/org/thoughtcrime/securesms/migrations/ApplyUnknownFieldsToSelfMigrationJob.java @@ -7,10 +7,8 @@ import com.google.protobuf.InvalidProtocolBufferException; import org.signal.core.util.logging.Log; import org.thoughtcrime.securesms.database.DatabaseFactory; import org.thoughtcrime.securesms.database.RecipientDatabase; -import org.thoughtcrime.securesms.dependencies.ApplicationDependencies; import org.thoughtcrime.securesms.jobmanager.Data; import org.thoughtcrime.securesms.jobmanager.Job; -import org.thoughtcrime.securesms.jobs.StorageSyncJob; import org.thoughtcrime.securesms.recipients.Recipient; import org.thoughtcrime.securesms.storage.StorageSyncHelper; import org.thoughtcrime.securesms.util.TextSecurePreferences; @@ -47,7 +45,7 @@ public class ApplyUnknownFieldsToSelfMigrationJob extends MigrationJob { @Override public void performMigration() { - if (!TextSecurePreferences.isPushRegistered(context) || TextSecurePreferences.getLocalUuid(context) == null) { + if (!TextSecurePreferences.isPushRegistered(context) || TextSecurePreferences.getLocalAci(context) == null) { Log.w(TAG, "Not registered!"); return; } diff --git a/app/src/main/java/org/thoughtcrime/securesms/migrations/DirectoryRefreshMigrationJob.java b/app/src/main/java/org/thoughtcrime/securesms/migrations/DirectoryRefreshMigrationJob.java index 1d24c034b0..b37e0ad11c 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/migrations/DirectoryRefreshMigrationJob.java +++ b/app/src/main/java/org/thoughtcrime/securesms/migrations/DirectoryRefreshMigrationJob.java @@ -42,7 +42,7 @@ public final class DirectoryRefreshMigrationJob extends MigrationJob { public void performMigration() throws IOException { if (!TextSecurePreferences.isPushRegistered(context) || !SignalStore.registrationValues().isRegistrationComplete() || - TextSecurePreferences.getLocalUuid(context) == null) + TextSecurePreferences.getLocalAci(context) == null) { Log.w(TAG, "Not registered! Skipping."); return; diff --git a/app/src/main/java/org/thoughtcrime/securesms/migrations/StorageServiceMigrationJob.java b/app/src/main/java/org/thoughtcrime/securesms/migrations/StorageServiceMigrationJob.java index 486301a97e..86939e2a3c 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/migrations/StorageServiceMigrationJob.java +++ b/app/src/main/java/org/thoughtcrime/securesms/migrations/StorageServiceMigrationJob.java @@ -42,7 +42,7 @@ public class StorageServiceMigrationJob extends MigrationJob { @Override public void performMigration() { - if (TextSecurePreferences.getLocalUuid(context) == null) { + if (TextSecurePreferences.getLocalAci(context) == null) { Log.w(TAG, "Self not yet available."); return; } diff --git a/app/src/main/java/org/thoughtcrime/securesms/migrations/UserNotificationMigrationJob.java b/app/src/main/java/org/thoughtcrime/securesms/migrations/UserNotificationMigrationJob.java index f002209469..f78a751b02 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/migrations/UserNotificationMigrationJob.java +++ b/app/src/main/java/org/thoughtcrime/securesms/migrations/UserNotificationMigrationJob.java @@ -58,7 +58,7 @@ public class UserNotificationMigrationJob extends MigrationJob { void performMigration() { if (!TextSecurePreferences.isPushRegistered(context) || TextSecurePreferences.getLocalNumber(context) == null || - TextSecurePreferences.getLocalUuid(context) == null) + TextSecurePreferences.getLocalAci(context) == null) { Log.w(TAG, "Not registered! Skipping."); return; diff --git a/app/src/main/java/org/thoughtcrime/securesms/migrations/UuidMigrationJob.java b/app/src/main/java/org/thoughtcrime/securesms/migrations/UuidMigrationJob.java index 5835ddbc7f..49ab54b00e 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/migrations/UuidMigrationJob.java +++ b/app/src/main/java/org/thoughtcrime/securesms/migrations/UuidMigrationJob.java @@ -14,6 +14,7 @@ import org.thoughtcrime.securesms.jobmanager.impl.NetworkConstraint; import org.thoughtcrime.securesms.recipients.Recipient; import org.thoughtcrime.securesms.recipients.RecipientId; import org.thoughtcrime.securesms.util.TextSecurePreferences; +import org.whispersystems.signalservice.api.push.ACI; import java.io.IOException; import java.util.UUID; @@ -70,10 +71,10 @@ public class UuidMigrationJob extends MigrationJob { private static void fetchOwnUuid(@NonNull Context context) throws IOException { RecipientId self = Recipient.self().getId(); - UUID localUuid = ApplicationDependencies.getSignalServiceAccountManager().getOwnUuid(); + ACI localUuid = ApplicationDependencies.getSignalServiceAccountManager().getOwnAci(); DatabaseFactory.getRecipientDatabase(context).markRegisteredOrThrow(self, localUuid); - TextSecurePreferences.setLocalUuid(context, localUuid); + TextSecurePreferences.setLocalAci(context, localUuid); } public static class Factory implements Job.Factory { diff --git a/app/src/main/java/org/thoughtcrime/securesms/mms/MessageGroupContext.java b/app/src/main/java/org/thoughtcrime/securesms/mms/MessageGroupContext.java index ac9e5fc69f..baf8a32e53 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/mms/MessageGroupContext.java +++ b/app/src/main/java/org/thoughtcrime/securesms/mms/MessageGroupContext.java @@ -15,6 +15,7 @@ import org.thoughtcrime.securesms.recipients.Recipient; import org.thoughtcrime.securesms.recipients.RecipientId; import org.thoughtcrime.securesms.util.Base64; import org.whispersystems.signalservice.api.groupsv2.DecryptedGroupUtil; +import org.whispersystems.signalservice.api.push.ACI; import org.whispersystems.signalservice.api.push.SignalServiceAddress; import org.whispersystems.signalservice.api.util.UuidUtil; import org.whispersystems.signalservice.internal.push.SignalServiceProtos.GroupContext; @@ -191,7 +192,7 @@ public final class MessageGroupContext { List members = new ArrayList<>(decryptedGroupV2Context.getGroupState().getMembersCount()); for (DecryptedMember member : decryptedGroupV2Context.getGroupState().getMembersList()) { - RecipientId recipient = RecipientId.from(UuidUtil.fromByteString(member.getUuid()), null); + RecipientId recipient = RecipientId.from(ACI.fromByteString(member.getUuid()), null); if (!Recipient.self().getId().equals(recipient)) { members.add(recipient); } diff --git a/app/src/main/java/org/thoughtcrime/securesms/push/AccountManagerFactory.java b/app/src/main/java/org/thoughtcrime/securesms/push/AccountManagerFactory.java index 8e52fae15b..c66484f84f 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/push/AccountManagerFactory.java +++ b/app/src/main/java/org/thoughtcrime/securesms/push/AccountManagerFactory.java @@ -11,6 +11,7 @@ import org.signal.core.util.logging.Log; import org.thoughtcrime.securesms.BuildConfig; import org.thoughtcrime.securesms.util.FeatureFlags; import org.whispersystems.signalservice.api.SignalServiceAccountManager; +import org.whispersystems.signalservice.api.push.ACI; import java.util.UUID; @@ -19,7 +20,7 @@ public class AccountManagerFactory { private static final String TAG = Log.tag(AccountManagerFactory.class); public static @NonNull SignalServiceAccountManager createAuthenticated(@NonNull Context context, - @NonNull UUID uuid, + @NonNull ACI aci, @NonNull String number, @NonNull String password) { @@ -34,7 +35,11 @@ public class AccountManagerFactory { } return new SignalServiceAccountManager(new SignalServiceNetworkAccess(context).getConfiguration(number), - uuid, number, password, BuildConfig.SIGNAL_AGENT, FeatureFlags.okHttpAutomaticRetry()); + aci, + number, + password, + BuildConfig.SIGNAL_AGENT, + FeatureFlags.okHttpAutomaticRetry()); } /** diff --git a/app/src/main/java/org/thoughtcrime/securesms/recipients/LiveRecipientCache.java b/app/src/main/java/org/thoughtcrime/securesms/recipients/LiveRecipientCache.java index a934a48abd..20ff868a3e 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/recipients/LiveRecipientCache.java +++ b/app/src/main/java/org/thoughtcrime/securesms/recipients/LiveRecipientCache.java @@ -22,6 +22,7 @@ import org.thoughtcrime.securesms.util.LRUCache; import org.thoughtcrime.securesms.util.Stopwatch; import org.thoughtcrime.securesms.util.TextSecurePreferences; import org.thoughtcrime.securesms.util.concurrent.FilteredExecutor; +import org.whispersystems.signalservice.api.push.ACI; import java.util.ArrayList; import java.util.Collection; @@ -160,11 +161,11 @@ public final class LiveRecipientCache { } if (selfId == null) { - UUID localUuid = TextSecurePreferences.getLocalUuid(context); + ACI localAci = TextSecurePreferences.getLocalAci(context); String localE164 = TextSecurePreferences.getLocalNumber(context); - if (localUuid != null) { - selfId = recipientDatabase.getByUuid(localUuid).or(recipientDatabase.getByE164(localE164)).orNull(); + if (localAci != null) { + selfId = recipientDatabase.getByAci(localAci).or(recipientDatabase.getByE164(localE164)).orNull(); } else if (localE164 != null) { selfId = recipientDatabase.getByE164(localE164).orNull(); } else { diff --git a/app/src/main/java/org/thoughtcrime/securesms/recipients/Recipient.java b/app/src/main/java/org/thoughtcrime/securesms/recipients/Recipient.java index 726192ef7f..d7d0b490bf 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/recipients/Recipient.java +++ b/app/src/main/java/org/thoughtcrime/securesms/recipients/Recipient.java @@ -33,6 +33,7 @@ import org.thoughtcrime.securesms.database.RecipientDatabase.MentionSetting; import org.thoughtcrime.securesms.database.RecipientDatabase.RegisteredState; import org.thoughtcrime.securesms.database.RecipientDatabase.UnidentifiedAccessMode; import org.thoughtcrime.securesms.database.RecipientDatabase.VibrateState; +import org.whispersystems.signalservice.api.push.ACI; import org.thoughtcrime.securesms.database.model.databaseprotos.RecipientExtras; import org.thoughtcrime.securesms.dependencies.ApplicationDependencies; import org.thoughtcrime.securesms.groups.GroupId; @@ -77,7 +78,7 @@ public class Recipient { private final RecipientId id; private final boolean resolving; - private final UUID uuid; + private final ACI aci; private final String username; private final String e164; private final String email; @@ -163,8 +164,8 @@ public class Recipient { * Returns a fully-populated {@link Recipient} and associates it with the provided username. */ @WorkerThread - public static @NonNull Recipient externalUsername(@NonNull Context context, @NonNull UUID uuid, @NonNull String username) { - Recipient recipient = externalPush(context, uuid, null, false); + public static @NonNull Recipient externalUsername(@NonNull Context context, @NonNull ACI aci, @NonNull String username) { + Recipient recipient = externalPush(context, aci, null, false); DatabaseFactory.getRecipientDatabase(context).setUsername(recipient.getId(), username); return recipient; } @@ -172,11 +173,11 @@ public class Recipient { /** * Returns a fully-populated {@link Recipient} based off of a {@link SignalServiceAddress}, * creating one in the database if necessary. Convenience overload of - * {@link #externalPush(Context, UUID, String, boolean)} + * {@link #externalPush(Context, ACI, String, boolean)} */ @WorkerThread public static @NonNull Recipient externalPush(@NonNull Context context, @NonNull SignalServiceAddress signalServiceAddress) { - return externalPush(context, signalServiceAddress.getUuid(), signalServiceAddress.getNumber().orNull(), false); + return externalPush(context, signalServiceAddress.getAci(), signalServiceAddress.getNumber().orNull(), false); } /** @@ -189,7 +190,7 @@ public class Recipient { if (address.getNumber().isPresent()) { return externalPush(context, null, address.getNumber().get(), false); } else { - return externalPush(context, address.getUuid(), null, false); + return externalPush(context, address.getAci(), null, false); } } @@ -204,7 +205,7 @@ public class Recipient { */ @WorkerThread public static @NonNull Recipient externalHighTrustPush(@NonNull Context context, @NonNull SignalServiceAddress signalServiceAddress) { - return externalPush(context, signalServiceAddress.getUuid(), signalServiceAddress.getNumber().orNull(), true); + return externalPush(context, signalServiceAddress.getAci(), signalServiceAddress.getNumber().orNull(), true); } /** @@ -220,19 +221,19 @@ public class Recipient { * that can be trusted as accurate (like an envelope). */ @WorkerThread - public static @NonNull Recipient externalPush(@NonNull Context context, @Nullable UUID uuid, @Nullable String e164, boolean highTrust) { - if (UuidUtil.UNKNOWN_UUID.equals(uuid)) { + public static @NonNull Recipient externalPush(@NonNull Context context, @Nullable ACI aci, @Nullable String e164, boolean highTrust) { + if (UuidUtil.UNKNOWN_UUID.equals(aci)) { throw new AssertionError(); } RecipientDatabase db = DatabaseFactory.getRecipientDatabase(context); - RecipientId recipientId = db.getAndPossiblyMerge(uuid, e164, highTrust); + RecipientId recipientId = db.getAndPossiblyMerge(aci, e164, highTrust); Recipient resolved = resolved(recipientId); - if (highTrust && !resolved.isRegistered() && uuid != null) { + if (highTrust && !resolved.isRegistered() && aci != null) { Log.w(TAG, "External high-trust push was locally marked unregistered. Marking as registered."); - db.markRegistered(recipientId, uuid); + db.markRegistered(recipientId, aci); } else if (highTrust && !resolved.isRegistered()) { Log.w(TAG, "External high-trust push was locally marked unregistered, but we don't have a UUID, so we can't do anything.", new Throwable()); } @@ -298,7 +299,7 @@ public class Recipient { * or serialized groupId. * * If the identifier is a UUID of a Signal user, prefer using - * {@link #externalPush(Context, UUID, String, boolean)} or its overload, as this will let us associate + * {@link #externalPush(Context, ACI, String, boolean)} or its overload, as this will let us associate * the phone number with the recipient. */ @WorkerThread @@ -309,8 +310,8 @@ public class Recipient { RecipientId id = null; if (UuidUtil.isUuid(identifier)) { - UUID uuid = UuidUtil.parseOrThrow(identifier); - id = db.getOrInsertFromUuid(uuid); + ACI uuid = ACI.parseOrThrow(identifier); + id = db.getOrInsertFromAci(uuid); } else if (GroupId.isEncodedGroup(identifier)) { id = db.getOrInsertFromGroupId(GroupId.parseOrThrow(identifier)); } else if (NumberUtil.isValidEmail(identifier)) { @@ -329,9 +330,9 @@ public class Recipient { Recipient(@NonNull RecipientId id) { this.id = id; - this.resolving = true; - this.uuid = null; - this.username = null; + this.resolving = true; + this.aci = null; + this.username = null; this.e164 = null; this.email = null; this.groupId = null; @@ -384,7 +385,7 @@ public class Recipient { public Recipient(@NonNull RecipientId id, @NonNull RecipientDetails details, boolean resolved) { this.id = id; this.resolving = !resolved; - this.uuid = details.uuid; + this.aci = details.aci; this.username = details.username; this.e164 = details.e164; this.email = details.email; @@ -603,8 +604,8 @@ public class Recipient { return StringUtil.isolateBidi(name); } - public @NonNull Optional getUuid() { - return Optional.fromNullable(uuid); + public @NonNull Optional getAci() { + return Optional.fromNullable(aci); } public @NonNull Optional getUsername() { @@ -631,8 +632,8 @@ public class Recipient { return Optional.fromNullable(e164).or(Optional.fromNullable(email)); } - public @NonNull UUID requireUuid() { - UUID resolved = resolving ? resolve().uuid : uuid; + public @NonNull ACI requireAci() { + ACI resolved = resolving ? resolve().aci : aci; if (resolved == null) { throw new MissingAddressError(id); @@ -682,12 +683,12 @@ public class Recipient { return getE164().isPresent(); } - public boolean hasUuid() { - return getUuid().isPresent(); + public boolean hasAci() { + return getAci().isPresent(); } - public boolean isUuidOnly() { - return hasUuid() && !hasSmsAddress(); + public boolean isAciOnly() { + return hasAci() && !hasSmsAddress(); } public @NonNull GroupId requireGroupId() { @@ -701,18 +702,18 @@ public class Recipient { } public boolean hasServiceIdentifier() { - return uuid != null || e164 != null; + return aci != null || e164 != null; } /** - * @return A string identifier able to be used with the Signal service. Prefers UUID, and if not + * @return A string identifier able to be used with the Signal service. Prefers ACI, and if not * available, will return an E164 number. */ public @NonNull String requireServiceId() { Recipient resolved = resolving ? resolve() : this; - if (resolved.getUuid().isPresent()) { - return resolved.getUuid().get().toString(); + if (resolved.getAci().isPresent()) { + return resolved.requireAci().toString(); } else { return getE164().get(); } @@ -721,15 +722,15 @@ public class Recipient { /** * @return A single string to represent the recipient, in order of precedence: * - * Group ID > UUID > Phone > Email + * Group ID > ACI > Phone > Email */ public @NonNull String requireStringId() { Recipient resolved = resolving ? resolve() : this; if (resolved.isGroup()) { return resolved.requireGroupId().toString(); - } else if (resolved.getUuid().isPresent()) { - return resolved.getUuid().get().toString(); + } else if (resolved.getAci().isPresent()) { + return resolved.requireAci().toString(); } return requireSmsAddress(); @@ -1183,7 +1184,7 @@ public class Recipient { lastProfileFetch == other.lastProfileFetch && forceSmsSelection == other.forceSmsSelection && Objects.equals(id, other.id) && - Objects.equals(uuid, other.uuid) && + Objects.equals(aci, other.aci) && Objects.equals(username, other.username) && Objects.equals(e164, other.e164) && Objects.equals(email, other.email) && diff --git a/app/src/main/java/org/thoughtcrime/securesms/recipients/RecipientDetails.java b/app/src/main/java/org/thoughtcrime/securesms/recipients/RecipientDetails.java index d2640e146e..562ef68d4a 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/recipients/RecipientDetails.java +++ b/app/src/main/java/org/thoughtcrime/securesms/recipients/RecipientDetails.java @@ -22,15 +22,15 @@ import org.thoughtcrime.securesms.util.TextSecurePreferences; import org.thoughtcrime.securesms.util.Util; import org.thoughtcrime.securesms.wallpaper.ChatWallpaper; import org.whispersystems.libsignal.util.guava.Optional; +import org.whispersystems.signalservice.api.push.ACI; import java.util.Collections; import java.util.LinkedList; import java.util.List; -import java.util.UUID; public class RecipientDetails { - final UUID uuid; + final ACI aci; final String username; final String e164; final String email; @@ -94,7 +94,7 @@ public class RecipientDetails { this.systemContactPhoto = Util.uri(settings.getSystemContactPhotoUri()); this.customLabel = settings.getSystemPhoneLabel(); this.contactUri = Util.uri(settings.getSystemContactUri()); - this.uuid = settings.getUuid(); + this.aci = settings.getAci(); this.username = settings.getUsername(); this.e164 = settings.getE164(); this.email = settings.getEmail(); @@ -149,9 +149,9 @@ public class RecipientDetails { this.groupAvatarId = null; this.systemContactPhoto = null; this.customLabel = null; - this.contactUri = null; - this.uuid = null; - this.username = null; + this.contactUri = null; + this.aci = null; + this.username = null; this.e164 = null; this.email = null; this.groupId = null; @@ -201,7 +201,7 @@ public class RecipientDetails { public static @NonNull RecipientDetails forIndividual(@NonNull Context context, @NonNull RecipientSettings settings) { boolean systemContact = !settings.getSystemProfileName().isEmpty(); boolean isSelf = (settings.getE164() != null && settings.getE164().equals(TextSecurePreferences.getLocalNumber(context))) || - (settings.getUuid() != null && settings.getUuid().equals(TextSecurePreferences.getLocalUuid(context))); + (settings.getAci() != null && settings.getAci().equals(TextSecurePreferences.getLocalAci(context))); RegisteredState registeredState = settings.getRegistered(); diff --git a/app/src/main/java/org/thoughtcrime/securesms/recipients/RecipientId.java b/app/src/main/java/org/thoughtcrime/securesms/recipients/RecipientId.java index e9e6e3efa8..f53c82f3d0 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/recipients/RecipientId.java +++ b/app/src/main/java/org/thoughtcrime/securesms/recipients/RecipientId.java @@ -14,6 +14,7 @@ import com.annimon.stream.Stream; import org.thoughtcrime.securesms.dependencies.ApplicationDependencies; import org.thoughtcrime.securesms.util.DelimiterUtil; import org.thoughtcrime.securesms.util.Util; +import org.whispersystems.signalservice.api.push.ACI; import org.whispersystems.signalservice.api.push.SignalServiceAddress; import org.whispersystems.signalservice.api.util.UuidUtil; @@ -54,7 +55,7 @@ public class RecipientId implements Parcelable, Comparable { @AnyThread public static @NonNull RecipientId from(@NonNull SignalServiceAddress address) { - return from(address.getUuid(), address.getNumber().orNull(), false); + return from(address.getAci(), address.getNumber().orNull(), false); } /** @@ -65,7 +66,7 @@ public class RecipientId implements Parcelable, Comparable { @AnyThread public static @NonNull RecipientId fromExternalPush(@NonNull String identifier) { if (UuidUtil.isUuid(identifier)) { - return from(UuidUtil.parseOrThrow(identifier), null); + return from(ACI.parseOrThrow(identifier), null); } else { return from(null, identifier); } @@ -77,7 +78,7 @@ public class RecipientId implements Parcelable, Comparable { */ @AnyThread public static @NonNull RecipientId fromHighTrust(@NonNull SignalServiceAddress address) { - return from(address.getUuid(), address.getNumber().orNull(), true); + return from(address.getAci(), address.getNumber().orNull(), true); } /** @@ -85,17 +86,17 @@ public class RecipientId implements Parcelable, Comparable { */ @AnyThread @SuppressLint("WrongThread") - public static @NonNull RecipientId from(@Nullable UUID uuid, @Nullable String e164) { - return from(uuid, e164, false); + public static @NonNull RecipientId from(@Nullable ACI aci, @Nullable String e164) { + return from(aci, e164, false); } @AnyThread @SuppressLint("WrongThread") - private static @NonNull RecipientId from(@Nullable UUID uuid, @Nullable String e164, boolean highTrust) { - RecipientId recipientId = RecipientIdCache.INSTANCE.get(uuid, e164); + private static @NonNull RecipientId from(@Nullable ACI aci, @Nullable String e164, boolean highTrust) { + RecipientId recipientId = RecipientIdCache.INSTANCE.get(aci, e164); if (recipientId == null) { - Recipient recipient = Recipient.externalPush(ApplicationDependencies.getApplication(), uuid, e164, highTrust); + Recipient recipient = Recipient.externalPush(ApplicationDependencies.getApplication(), aci, e164, highTrust); RecipientIdCache.INSTANCE.put(recipient); recipientId = recipient.getId(); } diff --git a/app/src/main/java/org/thoughtcrime/securesms/recipients/RecipientIdCache.java b/app/src/main/java/org/thoughtcrime/securesms/recipients/RecipientIdCache.java index afcfc0ebfc..b13c68ca9f 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/recipients/RecipientIdCache.java +++ b/app/src/main/java/org/thoughtcrime/securesms/recipients/RecipientIdCache.java @@ -5,6 +5,7 @@ import androidx.annotation.Nullable; import org.signal.core.util.logging.Log; import org.whispersystems.libsignal.util.guava.Optional; +import org.whispersystems.signalservice.api.push.ACI; import java.util.LinkedHashMap; import java.util.Map; @@ -35,35 +36,35 @@ final class RecipientIdCache { synchronized void put(@NonNull Recipient recipient) { RecipientId recipientId = recipient.getId(); Optional e164 = recipient.getE164(); - Optional uuid = recipient.getUuid(); + Optional aci = recipient.getAci(); if (e164.isPresent()) { ids.put(e164.get(), recipientId); } - if (uuid.isPresent()) { - ids.put(uuid.get(), recipientId); + if (aci.isPresent()) { + ids.put(aci.get(), recipientId); } } - synchronized @Nullable RecipientId get(@Nullable UUID uuid, @Nullable String e164) { - if (uuid != null && e164 != null) { - RecipientId recipientIdByUuid = ids.get(uuid); - if (recipientIdByUuid == null) return null; + synchronized @Nullable RecipientId get(@Nullable ACI aci, @Nullable String e164) { + if (aci != null && e164 != null) { + RecipientId recipientIdByAci = ids.get(aci); + if (recipientIdByAci == null) return null; RecipientId recipientIdByE164 = ids.get(e164); if (recipientIdByE164 == null) return null; - if (recipientIdByUuid.equals(recipientIdByE164)) { - return recipientIdByUuid; + if (recipientIdByAci.equals(recipientIdByE164)) { + return recipientIdByAci; } else { - ids.remove(uuid); + ids.remove(aci); ids.remove(e164); Log.w(TAG, "Seen invalid RecipientIdCacheState"); return null; } - } else if (uuid != null) { - return ids.get(uuid); + } else if (aci != null) { + return ids.get(aci); } else if (e164 != null) { return ids.get(e164); } diff --git a/app/src/main/java/org/thoughtcrime/securesms/recipients/RecipientUtil.java b/app/src/main/java/org/thoughtcrime/securesms/recipients/RecipientUtil.java index ee088c607d..d66dd189d9 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/recipients/RecipientUtil.java +++ b/app/src/main/java/org/thoughtcrime/securesms/recipients/RecipientUtil.java @@ -33,7 +33,6 @@ import org.whispersystems.signalservice.api.push.exceptions.NotFoundException; import java.io.IOException; import java.util.Collection; import java.util.List; -import java.util.stream.Collectors; public class RecipientUtil { @@ -50,11 +49,11 @@ public class RecipientUtil { { recipient = recipient.resolve(); - if (!recipient.getUuid().isPresent() && !recipient.getE164().isPresent()) { + if (!recipient.getAci().isPresent() && !recipient.getE164().isPresent()) { throw new AssertionError(recipient.getId() + " - No UUID or phone number!"); } - if (!recipient.getUuid().isPresent()) { + if (!recipient.getAci().isPresent()) { Log.i(TAG, recipient.getId() + " is missing a UUID..."); RegisteredState state = DirectoryHelper.refreshDirectoryFor(context, recipient, false); @@ -62,8 +61,8 @@ public class RecipientUtil { Log.i(TAG, "Successfully performed a UUID fetch for " + recipient.getId() + ". Registered: " + state); } - if (recipient.hasUuid()) { - return new SignalServiceAddress(recipient.requireUuid(), Optional.fromNullable(recipient.resolve().getE164().orNull())); + if (recipient.hasAci()) { + return new SignalServiceAddress(recipient.requireAci(), Optional.fromNullable(recipient.resolve().getE164().orNull())); } else { throw new NotFoundException(recipient.getId() + " is not registered!"); } @@ -82,7 +81,7 @@ public class RecipientUtil { return Stream.of(recipients) .map(Recipient::resolve) - .map(r -> new SignalServiceAddress(r.requireUuid(), r.getE164().orNull())) + .map(r -> new SignalServiceAddress(r.requireAci(), r.getE164().orNull())) .toList(); } @@ -94,7 +93,7 @@ public class RecipientUtil { { List recipientsWithoutUuids = Stream.of(recipients) .map(Recipient::resolve) - .filterNot(Recipient::hasUuid) + .filterNot(Recipient::hasAci) .toList(); if (recipientsWithoutUuids.size() > 0) { diff --git a/app/src/main/java/org/thoughtcrime/securesms/registration/RegistrationRepository.java b/app/src/main/java/org/thoughtcrime/securesms/registration/RegistrationRepository.java index 6c7d6544cf..a39ccd0e02 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/registration/RegistrationRepository.java +++ b/app/src/main/java/org/thoughtcrime/securesms/registration/RegistrationRepository.java @@ -36,13 +36,13 @@ import org.whispersystems.libsignal.util.KeyHelper; import org.whispersystems.libsignal.util.guava.Optional; import org.whispersystems.signalservice.api.KbsPinData; import org.whispersystems.signalservice.api.SignalServiceAccountManager; +import org.whispersystems.signalservice.api.push.ACI; import org.whispersystems.signalservice.api.util.UuidUtil; import org.whispersystems.signalservice.internal.ServiceResponse; import org.whispersystems.signalservice.internal.push.VerifyAccountResponse; import java.io.IOException; import java.util.List; -import java.util.UUID; import io.reactivex.rxjava3.core.Single; import io.reactivex.rxjava3.schedulers.Schedulers; @@ -128,14 +128,14 @@ public final class RegistrationRepository { SessionUtil.archiveAllSessions(); SenderKeyUtil.clearAllState(context); - UUID uuid = UuidUtil.parseOrThrow(response.getUuid()); + ACI aci = ACI.parseOrThrow(response.getUuid()); boolean hasPin = response.isStorageCapable(); IdentityKeyPair identityKey = IdentityKeyUtil.getIdentityKeyPair(context); List records = PreKeyUtil.generatePreKeys(context); SignedPreKeyRecord signedPreKey = PreKeyUtil.generateSignedPreKey(context, identityKey, true); - SignalServiceAccountManager accountManager = AccountManagerFactory.createAuthenticated(context, uuid, registrationData.getE164(), registrationData.getPassword()); + SignalServiceAccountManager accountManager = AccountManagerFactory.createAuthenticated(context, aci, registrationData.getE164(), registrationData.getPassword()); accountManager.setPreKeys(identityKey.getPublicKey(), signedPreKey, records); if (registrationData.isFcm()) { @@ -143,13 +143,13 @@ public final class RegistrationRepository { } RecipientDatabase recipientDatabase = DatabaseFactory.getRecipientDatabase(context); - RecipientId selfId = Recipient.externalPush(context, uuid, registrationData.getE164(), true).getId(); + RecipientId selfId = Recipient.externalPush(context, aci, registrationData.getE164(), true).getId(); recipientDatabase.setProfileSharing(selfId, true); - recipientDatabase.markRegisteredOrThrow(selfId, uuid); + recipientDatabase.markRegisteredOrThrow(selfId, aci); TextSecurePreferences.setLocalNumber(context, registrationData.getE164()); - TextSecurePreferences.setLocalUuid(context, uuid); + TextSecurePreferences.setLocalAci(context, aci); recipientDatabase.setProfileKey(selfId, registrationData.getProfileKey()); ApplicationDependencies.getRecipientCache().clearSelf(); diff --git a/app/src/main/java/org/thoughtcrime/securesms/service/webrtc/GroupActionProcessor.java b/app/src/main/java/org/thoughtcrime/securesms/service/webrtc/GroupActionProcessor.java index bb108595b3..7ea7fbb4e1 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/service/webrtc/GroupActionProcessor.java +++ b/app/src/main/java/org/thoughtcrime/securesms/service/webrtc/GroupActionProcessor.java @@ -22,6 +22,7 @@ import org.thoughtcrime.securesms.service.webrtc.state.WebRtcServiceState; import org.thoughtcrime.securesms.service.webrtc.state.WebRtcServiceStateBuilder; import org.webrtc.VideoTrack; import org.whispersystems.signalservice.api.messages.calls.OfferMessage; +import org.whispersystems.signalservice.api.push.ACI; import java.util.ArrayList; import java.util.Collection; @@ -82,7 +83,7 @@ public class GroupActionProcessor extends DeviceAwareActionProcessor { seen.add(Recipient.self()); for (GroupCall.RemoteDeviceState device : remoteDeviceStates) { - Recipient recipient = Recipient.externalPush(context, device.getUserId(), null, false); + Recipient recipient = Recipient.externalPush(context, ACI.from(device.getUserId()), null, false); CallParticipantId callParticipantId = new CallParticipantId(device.getDemuxId(), recipient.getId()); CallParticipant callParticipant = participants.get(callParticipantId); diff --git a/app/src/main/java/org/thoughtcrime/securesms/service/webrtc/GroupConnectedActionProcessor.java b/app/src/main/java/org/thoughtcrime/securesms/service/webrtc/GroupConnectedActionProcessor.java index 0a806fd3df..7be8a1bb41 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/service/webrtc/GroupConnectedActionProcessor.java +++ b/app/src/main/java/org/thoughtcrime/securesms/service/webrtc/GroupConnectedActionProcessor.java @@ -122,8 +122,8 @@ public class GroupConnectedActionProcessor extends GroupActionProcessor { webRtcInteractor.sendGroupCallMessage(currentState.getCallInfoState().getCallRecipient(), eraId); List members = new ArrayList<>(peekInfo.getJoinedMembers()); - if (!members.contains(Recipient.self().requireUuid())) { - members.add(Recipient.self().requireUuid()); + if (!members.contains(Recipient.self().requireAci().uuid())) { + members.add(Recipient.self().requireAci().uuid()); } webRtcInteractor.updateGroupCallUpdateMessage(currentState.getCallInfoState().getCallRecipient().getId(), eraId, members, WebRtcUtil.isCallFull(peekInfo)); @@ -148,7 +148,7 @@ public class GroupConnectedActionProcessor extends GroupActionProcessor { String eraId = WebRtcUtil.getGroupCallEraId(groupCall); webRtcInteractor.sendGroupCallMessage(currentState.getCallInfoState().getCallRecipient(), eraId); - List members = Stream.of(currentState.getCallInfoState().getRemoteCallParticipants()).map(p -> p.getRecipient().requireUuid()).toList(); + List members = Stream.of(currentState.getCallInfoState().getRemoteCallParticipants()).map(p -> p.getRecipient().requireAci().uuid()).toList(); webRtcInteractor.updateGroupCallUpdateMessage(currentState.getCallInfoState().getCallRecipient().getId(), eraId, members, false); currentState = currentState.builder() diff --git a/app/src/main/java/org/thoughtcrime/securesms/service/webrtc/GroupPreJoinActionProcessor.java b/app/src/main/java/org/thoughtcrime/securesms/service/webrtc/GroupPreJoinActionProcessor.java index 4107dd5bb9..3c692f6ac6 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/service/webrtc/GroupPreJoinActionProcessor.java +++ b/app/src/main/java/org/thoughtcrime/securesms/service/webrtc/GroupPreJoinActionProcessor.java @@ -19,6 +19,7 @@ import org.thoughtcrime.securesms.service.webrtc.state.WebRtcServiceState; import org.thoughtcrime.securesms.service.webrtc.state.WebRtcServiceStateBuilder; import org.thoughtcrime.securesms.util.NetworkUtil; import org.whispersystems.signalservice.api.messages.calls.OfferMessage; +import org.whispersystems.signalservice.api.push.ACI; import java.util.List; @@ -108,7 +109,7 @@ public class GroupPreJoinActionProcessor extends GroupActionProcessor { } List callParticipants = Stream.of(peekInfo.getJoinedMembers()) - .map(uuid -> Recipient.externalPush(context, uuid, null, false)) + .map(uuid -> Recipient.externalPush(context, ACI.from(uuid), null, false)) .toList(); WebRtcServiceStateBuilder.CallInfoStateBuilder builder = currentState.builder() diff --git a/app/src/main/java/org/thoughtcrime/securesms/service/webrtc/IncomingGroupCallActionProcessor.java b/app/src/main/java/org/thoughtcrime/securesms/service/webrtc/IncomingGroupCallActionProcessor.java index 9238da73c4..132cc9be16 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/service/webrtc/IncomingGroupCallActionProcessor.java +++ b/app/src/main/java/org/thoughtcrime/securesms/service/webrtc/IncomingGroupCallActionProcessor.java @@ -24,6 +24,7 @@ import org.thoughtcrime.securesms.service.webrtc.state.WebRtcServiceState; import org.thoughtcrime.securesms.util.NetworkUtil; import org.thoughtcrime.securesms.webrtc.locks.LockManager; import org.whispersystems.libsignal.util.guava.Optional; +import org.whispersystems.signalservice.api.push.ACI; import java.util.UUID; @@ -136,7 +137,7 @@ public final class IncomingGroupCallActionProcessor extends DeviceAwareActionPro .changeCallSetupState() .isRemoteVideoOffer(true) .ringId(ringId) - .ringerRecipient(Recipient.externalPush(context, uuid, null, false)) + .ringerRecipient(Recipient.externalPush(context, ACI.from(uuid), null, false)) .commit() .changeCallInfoState() .callRecipient(remotePeerGroup.getRecipient()) diff --git a/app/src/main/java/org/thoughtcrime/securesms/service/webrtc/SignalCallManager.java b/app/src/main/java/org/thoughtcrime/securesms/service/webrtc/SignalCallManager.java index e54b0f6eb4..05327ccd41 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/service/webrtc/SignalCallManager.java +++ b/app/src/main/java/org/thoughtcrime/securesms/service/webrtc/SignalCallManager.java @@ -64,6 +64,7 @@ import org.whispersystems.signalservice.api.messages.calls.OfferMessage; import org.whispersystems.signalservice.api.messages.calls.OpaqueMessage; import org.whispersystems.signalservice.api.messages.calls.SignalServiceCallMessage; import org.whispersystems.signalservice.api.messages.calls.TurnServerInfo; +import org.whispersystems.signalservice.api.push.ACI; import org.whispersystems.signalservice.api.push.exceptions.UnregisteredUserException; import java.io.IOException; @@ -149,7 +150,7 @@ public final class SignalCallManager implements CallManager.Observer, GroupCall. serviceExecutor.execute(() -> { if (needsToSetSelfUuid) { try { - callManager.setSelfUuid(Recipient.self().requireUuid()); + callManager.setSelfUuid(Recipient.self().requireAci().uuid()); needsToSetSelfUuid = false; } catch (CallException e) { Log.w(TAG, "Unable to set self UUID on CallManager", e); @@ -593,7 +594,7 @@ public final class SignalCallManager implements CallManager.Observer, GroupCall. SignalServiceCallMessage callMessage = SignalServiceCallMessage.forOpaque(opaqueMessage, true, null); networkExecutor.execute(() -> { - Recipient recipient = Recipient.resolved(RecipientId.from(uuid, null)); + Recipient recipient = Recipient.resolved(RecipientId.from(ACI.from(uuid), null)); if (recipient.isBlocked()) { return; } diff --git a/app/src/main/java/org/thoughtcrime/securesms/storage/ContactRecordProcessor.java b/app/src/main/java/org/thoughtcrime/securesms/storage/ContactRecordProcessor.java index 482bf98f5f..7764ab35eb 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/storage/ContactRecordProcessor.java +++ b/app/src/main/java/org/thoughtcrime/securesms/storage/ContactRecordProcessor.java @@ -11,6 +11,7 @@ import org.thoughtcrime.securesms.database.RecipientDatabase; import org.thoughtcrime.securesms.recipients.Recipient; import org.thoughtcrime.securesms.recipients.RecipientId; import org.whispersystems.libsignal.util.guava.Optional; +import org.whispersystems.signalservice.api.push.ACI; import org.whispersystems.signalservice.api.push.SignalServiceAddress; import org.whispersystems.signalservice.api.storage.SignalContactRecord; import org.whispersystems.signalservice.api.util.UuidUtil; @@ -50,10 +51,10 @@ public class ContactRecordProcessor extends DefaultStorageRecordProcessor getMatching(@NonNull SignalContactRecord remote, @NonNull StorageKeyGenerator keyGenerator) { SignalServiceAddress address = remote.getAddress(); - Optional byUuid = recipientDatabase.getByUuid(address.getUuid()); + Optional byUuid = recipientDatabase.getByAci(address.getAci()); Optional byE164 = address.getNumber().isPresent() ? recipientDatabase.getByE164(address.getNumber().get()) : Optional.absent(); return byUuid.or(byE164).transform(recipientDatabase::getRecipientSettingsForSync) @@ -97,9 +98,9 @@ public class ContactRecordProcessor extends DefaultStorageRecordProcessor { Recipient recipient = Recipient.external(activity, e164); - if (!recipient.isRegistered() || !recipient.hasUuid()) { + if (!recipient.isRegistered() || !recipient.hasAci()) { try { DirectoryHelper.refreshDirectoryFor(activity, recipient, false); recipient = Recipient.resolved(recipient.getId()); diff --git a/app/src/main/java/org/thoughtcrime/securesms/util/LocaleFeatureFlags.java b/app/src/main/java/org/thoughtcrime/securesms/util/LocaleFeatureFlags.java index de3abd8421..e57c00b41e 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/util/LocaleFeatureFlags.java +++ b/app/src/main/java/org/thoughtcrime/securesms/util/LocaleFeatureFlags.java @@ -72,12 +72,12 @@ public final class LocaleFeatureFlags { Map countryCodeValues = parseCountryValues(serialized, 0); Recipient self = Recipient.self(); - if (countryCodeValues.isEmpty() || !self.getE164().isPresent() || !self.getUuid().isPresent()) { + if (countryCodeValues.isEmpty() || !self.getE164().isPresent() || !self.getAci().isPresent()) { return false; } long countEnabled = getCountryValue(countryCodeValues, self.getE164().or(""), 0); - long currentUserBucket = BucketingUtil.bucket(flag, self.requireUuid(), 1_000_000); + long currentUserBucket = BucketingUtil.bucket(flag, self.requireAci().uuid(), 1_000_000); return countEnabled > currentUserBucket; } diff --git a/app/src/main/java/org/thoughtcrime/securesms/util/ProfileUtil.java b/app/src/main/java/org/thoughtcrime/securesms/util/ProfileUtil.java index bbc753d041..62434c1983 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/util/ProfileUtil.java +++ b/app/src/main/java/org/thoughtcrime/securesms/util/ProfileUtil.java @@ -284,7 +284,7 @@ public final class ProfileUtil { ProfileKey profileKey = ProfileKeyUtil.getSelfProfileKey(); SignalServiceAccountManager accountManager = ApplicationDependencies.getSignalServiceAccountManager(); - String avatarPath = accountManager.setVersionedProfile(Recipient.self().getUuid().get(), + String avatarPath = accountManager.setVersionedProfile(Recipient.self().requireAci(), profileKey, profileName.serialize(), about, @@ -321,8 +321,8 @@ public final class ProfileUtil { private static @NonNull SignalServiceAddress toSignalServiceAddress(@NonNull Context context, @NonNull Recipient recipient) throws IOException { if (recipient.getRegistered() == RecipientDatabase.RegisteredState.NOT_REGISTERED) { - if (recipient.hasUuid()) { - return new SignalServiceAddress(recipient.requireUuid(), recipient.getE164().orNull()); + if (recipient.hasAci()) { + return new SignalServiceAddress(recipient.requireAci(), recipient.getE164().orNull()); } else { throw new IOException(recipient.getId() + " not registered!"); } diff --git a/app/src/main/java/org/thoughtcrime/securesms/util/RecipientAccessList.kt b/app/src/main/java/org/thoughtcrime/securesms/util/RecipientAccessList.kt index 24b4fa4051..05b80f9f4b 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/util/RecipientAccessList.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/util/RecipientAccessList.kt @@ -2,9 +2,9 @@ package org.thoughtcrime.securesms.util import org.thoughtcrime.securesms.recipients.Recipient import org.thoughtcrime.securesms.recipients.RecipientId +import org.whispersystems.signalservice.api.push.ACI import org.whispersystems.signalservice.api.push.SignalServiceAddress import java.lang.IllegalArgumentException -import java.util.UUID /** * A list of Recipients, but with some helpful methods for retrieving them by various properties. Uses lazy properties to ensure that it will be as performant @@ -12,10 +12,10 @@ import java.util.UUID */ class RecipientAccessList(private val recipients: List) : List by recipients { - private val byUuid: Map by lazy { + private val byAci: Map by lazy { recipients - .filter { it.hasUuid() } - .associateBy { it.requireUuid() } + .filter { it.hasAci() } + .associateBy { it.requireAci() } } private val byE164: Map by lazy { @@ -25,10 +25,10 @@ class RecipientAccessList(private val recipients: List) : List fetchUuidForUsername(@NonNull Context context, @NonNull String username) { + public static @NonNull Optional fetchAciForUsername(@NonNull Context context, @NonNull String username) { Optional localId = DatabaseFactory.getRecipientDatabase(context).getByUsername(username); if (localId.isPresent()) { Recipient recipient = Recipient.resolved(localId.get()); - if (recipient.getUuid().isPresent()) { + if (recipient.getAci().isPresent()) { Log.i(TAG, "Found username locally -- using associated UUID."); - return recipient.getUuid(); + return recipient.getAci(); } else { Log.w(TAG, "Found username locally, but it had no associated UUID! Clearing it."); DatabaseFactory.getRecipientDatabase(context).clearUsernameIfExists(username); @@ -69,7 +69,7 @@ public class UsernameUtil { try { Log.d(TAG, "No local user with this username. Searching remotely."); SignalServiceProfile profile = ApplicationDependencies.getSignalServiceMessageReceiver().retrieveProfileByUsername(username, Optional.absent(), Locale.getDefault()); - return Optional.fromNullable(profile.getUuid()); + return Optional.fromNullable(profile.getAci()); } catch (IOException e) { return Optional.absent(); } diff --git a/app/src/test/java/org/thoughtcrime/securesms/contacts/sync/FuzzyPhoneNumberHelperTest.java b/app/src/test/java/org/thoughtcrime/securesms/contacts/sync/FuzzyPhoneNumberHelperTest.java index d898b6c81e..d6dfa1720c 100644 --- a/app/src/test/java/org/thoughtcrime/securesms/contacts/sync/FuzzyPhoneNumberHelperTest.java +++ b/app/src/test/java/org/thoughtcrime/securesms/contacts/sync/FuzzyPhoneNumberHelperTest.java @@ -3,13 +3,13 @@ package org.thoughtcrime.securesms.contacts.sync; import org.junit.Test; import org.thoughtcrime.securesms.contacts.sync.FuzzyPhoneNumberHelper.InputResult; import org.thoughtcrime.securesms.contacts.sync.FuzzyPhoneNumberHelper.OutputResult; +import org.whispersystems.signalservice.api.push.ACI; import org.whispersystems.signalservice.api.util.UuidUtil; import java.util.Arrays; import java.util.Collections; import java.util.HashSet; import java.util.Set; -import java.util.UUID; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertTrue; @@ -23,8 +23,8 @@ public class FuzzyPhoneNumberHelperTest { private static final String MX_A = "+525512345678"; private static final String MX_A_1 = "+5215512345678"; - private static final UUID UUID_A = UuidUtil.parseOrThrow("db980097-1e02-452f-9937-899630508705"); - private static final UUID UUID_B = UuidUtil.parseOrThrow("11ccd6de-8fcc-49d6-bb9e-df21ff88bd6f"); + private static final ACI ACI_A = ACI.parseOrThrow("db980097-1e02-452f-9937-899630508705"); + private static final ACI ACI_B = ACI.parseOrThrow("11ccd6de-8fcc-49d6-bb9e-df21ff88bd6f"); @Test public void generateInput_noMxNumbers() { @@ -100,65 +100,65 @@ public class FuzzyPhoneNumberHelperTest { @Test public void generateOutput_noMxNumbers() { - OutputResult result = FuzzyPhoneNumberHelper.generateOutput(mapOf(US_A, UUID_A, US_B, UUID_B), new InputResult(setOf(US_A, US_B), Collections.emptyMap())); + OutputResult result = FuzzyPhoneNumberHelper.generateOutput(mapOf(US_A, ACI_A, US_B, ACI_B), new InputResult(setOf(US_A, US_B), Collections.emptyMap())); assertEquals(2, result.getNumbers().size()); - assertEquals(UUID_A, result.getNumbers().get(US_A)); - assertEquals(UUID_B, result.getNumbers().get(US_B)); + assertEquals(ACI_A, result.getNumbers().get(US_A)); + assertEquals(ACI_B, result.getNumbers().get(US_B)); assertTrue(result.getRewrites().isEmpty()); } @Test public void generateOutput_bothMatch_no1To1() { - OutputResult result = FuzzyPhoneNumberHelper.generateOutput(mapOf(MX_A, UUID_A, MX_A_1, UUID_B), new InputResult(setOf(MX_A, MX_A_1), Collections.singletonMap(MX_A, MX_A_1))); + OutputResult result = FuzzyPhoneNumberHelper.generateOutput(mapOf(MX_A, ACI_A, MX_A_1, ACI_B), new InputResult(setOf(MX_A, MX_A_1), Collections.singletonMap(MX_A, MX_A_1))); assertEquals(1, result.getNumbers().size()); - assertEquals(UUID_A, result.getNumbers().get(MX_A)); + assertEquals(ACI_A, result.getNumbers().get(MX_A)); assertTrue(result.getRewrites().isEmpty()); } @Test public void generateOutput_bothMatch_1toNo1() { - OutputResult result = FuzzyPhoneNumberHelper.generateOutput(mapOf(MX_A, UUID_A, MX_A_1, UUID_B), new InputResult(setOf(MX_A, MX_A_1), Collections.singletonMap(MX_A_1, MX_A))); + OutputResult result = FuzzyPhoneNumberHelper.generateOutput(mapOf(MX_A, ACI_A, MX_A_1, ACI_B), new InputResult(setOf(MX_A, MX_A_1), Collections.singletonMap(MX_A_1, MX_A))); assertEquals(1, result.getNumbers().size()); - assertEquals(UUID_A, result.getNumbers().get(MX_A)); + assertEquals(ACI_A, result.getNumbers().get(MX_A)); assertEquals(MX_A, result.getRewrites().get(MX_A_1)); } @Test public void generateOutput_no1Match_no1To1() { - OutputResult result = FuzzyPhoneNumberHelper.generateOutput(mapOf(MX_A, UUID_A), new InputResult(setOf(MX_A, MX_A_1), Collections.singletonMap(MX_A, MX_A_1))); + OutputResult result = FuzzyPhoneNumberHelper.generateOutput(mapOf(MX_A, ACI_A), new InputResult(setOf(MX_A, MX_A_1), Collections.singletonMap(MX_A, MX_A_1))); assertEquals(1, result.getNumbers().size()); - assertEquals(UUID_A, result.getNumbers().get(MX_A)); + assertEquals(ACI_A, result.getNumbers().get(MX_A)); assertTrue(result.getRewrites().isEmpty()); } @Test public void generateOutput_no1Match_1ToNo1() { - OutputResult result = FuzzyPhoneNumberHelper.generateOutput(mapOf(MX_A, UUID_A), new InputResult(setOf(MX_A, MX_A_1), Collections.singletonMap(MX_A_1, MX_A))); + OutputResult result = FuzzyPhoneNumberHelper.generateOutput(mapOf(MX_A, ACI_A), new InputResult(setOf(MX_A, MX_A_1), Collections.singletonMap(MX_A_1, MX_A))); assertEquals(1, result.getNumbers().size()); - assertEquals(UUID_A, result.getNumbers().get(MX_A)); + assertEquals(ACI_A, result.getNumbers().get(MX_A)); assertEquals(MX_A, result.getRewrites().get(MX_A_1)); } @Test public void generateOutput_1Match_1ToNo1() { - OutputResult result = FuzzyPhoneNumberHelper.generateOutput(mapOf(MX_A_1, UUID_A), new InputResult(setOf(MX_A, MX_A_1), Collections.singletonMap(MX_A_1, MX_A))); + OutputResult result = FuzzyPhoneNumberHelper.generateOutput(mapOf(MX_A_1, ACI_A), new InputResult(setOf(MX_A, MX_A_1), Collections.singletonMap(MX_A_1, MX_A))); assertEquals(1, result.getNumbers().size()); - assertEquals(UUID_A, result.getNumbers().get(MX_A_1)); + assertEquals(ACI_A, result.getNumbers().get(MX_A_1)); assertTrue(result.getRewrites().isEmpty()); } @Test public void generateOutput_1Match_no1To1() { - OutputResult result = FuzzyPhoneNumberHelper.generateOutput(mapOf(MX_A_1, UUID_A), new InputResult(setOf(MX_A, MX_A_1), Collections.singletonMap(MX_A, MX_A_1))); + OutputResult result = FuzzyPhoneNumberHelper.generateOutput(mapOf(MX_A_1, ACI_A), new InputResult(setOf(MX_A, MX_A_1), Collections.singletonMap(MX_A, MX_A_1))); assertEquals(1, result.getNumbers().size()); - assertEquals(UUID_A, result.getNumbers().get(MX_A_1)); + assertEquals(ACI_A, result.getNumbers().get(MX_A_1)); assertEquals(MX_A_1, result.getRewrites().get(MX_A)); } diff --git a/app/src/test/java/org/thoughtcrime/securesms/database/RecipientDatabaseTestUtils.kt b/app/src/test/java/org/thoughtcrime/securesms/database/RecipientDatabaseTestUtils.kt index 4dbbe4db62..83e5937f83 100644 --- a/app/src/test/java/org/thoughtcrime/securesms/database/RecipientDatabaseTestUtils.kt +++ b/app/src/test/java/org/thoughtcrime/securesms/database/RecipientDatabaseTestUtils.kt @@ -12,6 +12,7 @@ import org.thoughtcrime.securesms.recipients.RecipientDetails import org.thoughtcrime.securesms.recipients.RecipientId import org.thoughtcrime.securesms.wallpaper.ChatWallpaper import org.whispersystems.libsignal.util.guava.Optional +import org.whispersystems.signalservice.api.push.ACI import java.util.UUID import kotlin.random.Random @@ -28,7 +29,7 @@ object RecipientDatabaseTestUtils { isSelf: Boolean = false, participants: List = listOf(), recipientId: RecipientId = RecipientId.from(Random.nextLong()), - uuid: UUID? = UUID.randomUUID(), + aci: ACI? = ACI.from(UUID.randomUUID()), username: String? = null, e164: String? = null, email: String? = null, @@ -89,7 +90,7 @@ object RecipientDatabaseTestUtils { registered, RecipientDatabase.RecipientSettings( recipientId, - uuid, + aci, username, e164, email, diff --git a/app/src/test/java/org/thoughtcrime/securesms/database/model/GroupsV2UpdateMessageProducerTest.java b/app/src/test/java/org/thoughtcrime/securesms/database/model/GroupsV2UpdateMessageProducerTest.java index 71df99ca1f..2e77cc4a6a 100644 --- a/app/src/test/java/org/thoughtcrime/securesms/database/model/GroupsV2UpdateMessageProducerTest.java +++ b/app/src/test/java/org/thoughtcrime/securesms/database/model/GroupsV2UpdateMessageProducerTest.java @@ -25,13 +25,14 @@ import org.signal.storageservice.protos.groups.local.DecryptedGroupChange; import org.signal.storageservice.protos.groups.local.DecryptedMember; import org.signal.storageservice.protos.groups.local.DecryptedPendingMember; import org.thoughtcrime.securesms.testutil.MainThreadUtil; -import org.thoughtcrime.securesms.util.Util; +import org.whispersystems.signalservice.api.push.ACI; import org.whispersystems.signalservice.api.util.UuidUtil; import java.util.Arrays; import java.util.List; import java.util.Map; import java.util.UUID; +import java.util.stream.Collectors; import static java.util.Collections.emptyList; import static java.util.Collections.singletonList; @@ -1350,12 +1351,14 @@ public final class GroupsV2UpdateMessageProducerTest { } private void assertSingleChangeMentioning(DecryptedGroupChange change, List expectedMentions) { + List expectedMentionAcis = expectedMentions.stream().map(ACI::from).collect(Collectors.toList()); + List changes = producer.describeChanges(null, change); assertThat(changes.size(), is(1)); UpdateDescription description = changes.get(0); - assertThat(description.getMentioned(), is(expectedMentions)); + assertThat(description.getMentioned(), is(expectedMentionAcis)); if (expectedMentions.isEmpty()) { assertTrue(description.isStringStatic()); @@ -1394,8 +1397,8 @@ public final class GroupsV2UpdateMessageProducerTest { } private static @NonNull GroupsV2UpdateMessageProducer.DescribeMemberStrategy createDescriber(@NonNull Map map) { - return uuid -> { - String name = map.get(uuid); + return aci -> { + String name = map.get(aci.uuid()); assertNotNull(name); return name; }; diff --git a/app/src/test/java/org/thoughtcrime/securesms/database/model/UpdateDescriptionTest.java b/app/src/test/java/org/thoughtcrime/securesms/database/model/UpdateDescriptionTest.java index ce0e6ce9a5..cd882834dd 100644 --- a/app/src/test/java/org/thoughtcrime/securesms/database/model/UpdateDescriptionTest.java +++ b/app/src/test/java/org/thoughtcrime/securesms/database/model/UpdateDescriptionTest.java @@ -6,6 +6,7 @@ import org.junit.runner.RunWith; import org.powermock.core.classloader.annotations.PrepareForTest; import org.powermock.modules.junit4.PowerMockRunner; import org.signal.core.util.ThreadUtil; +import org.whispersystems.signalservice.api.push.ACI; import java.util.Arrays; import java.util.Collections; @@ -50,7 +51,7 @@ public final class UpdateDescriptionTest { @Test(expected = AssertionError.class) public void stringFactory_cannot_run_on_main_thread() { - UpdateDescription description = UpdateDescription.mentioning(Collections.singletonList(UUID.randomUUID()), () -> "update", 0); + UpdateDescription description = UpdateDescription.mentioning(Collections.singletonList(ACI.from(UUID.randomUUID())), () -> "update", 0); setMainThread(true); @@ -59,7 +60,7 @@ public final class UpdateDescriptionTest { @Test(expected = UnsupportedOperationException.class) public void stringFactory_cannot_call_static_string() { - UpdateDescription description = UpdateDescription.mentioning(Collections.singletonList(UUID.randomUUID()), () -> "update", 0); + UpdateDescription description = UpdateDescription.mentioning(Collections.singletonList(ACI.from(UUID.randomUUID())), () -> "update", 0); description.getStaticString(); } @@ -73,7 +74,7 @@ public final class UpdateDescriptionTest { return "update"; }; - UpdateDescription description = UpdateDescription.mentioning(Collections.singletonList(UUID.randomUUID()), stringFactory, 0); + UpdateDescription description = UpdateDescription.mentioning(Collections.singletonList(ACI.from(UUID.randomUUID())), stringFactory, 0); assertEquals(0, factoryCalls.get()); @@ -89,7 +90,7 @@ public final class UpdateDescriptionTest { public void stringFactory_reevaluated_on_every_call() { AtomicInteger factoryCalls = new AtomicInteger(); UpdateDescription.StringFactory stringFactory = () -> "call" + factoryCalls.incrementAndGet(); - UpdateDescription description = UpdateDescription.mentioning(Collections.singletonList(UUID.randomUUID()), stringFactory, 0); + UpdateDescription description = UpdateDescription.mentioning(Collections.singletonList(ACI.from(UUID.randomUUID())), stringFactory, 0); setMainThread(false); @@ -125,8 +126,8 @@ public final class UpdateDescriptionTest { AtomicInteger factoryCalls2 = new AtomicInteger(); UpdateDescription.StringFactory stringFactory1 = () -> "update." + factoryCalls1.incrementAndGet(); UpdateDescription.StringFactory stringFactory2 = () -> "update." + factoryCalls2.incrementAndGet(); - UpdateDescription description1 = UpdateDescription.mentioning(Collections.singletonList(UUID.randomUUID()), stringFactory1, 0); - UpdateDescription description2 = UpdateDescription.mentioning(Collections.singletonList(UUID.randomUUID()), stringFactory2, 0); + UpdateDescription description1 = UpdateDescription.mentioning(Collections.singletonList(ACI.from(UUID.randomUUID())), stringFactory1, 0); + UpdateDescription description2 = UpdateDescription.mentioning(Collections.singletonList(ACI.from(UUID.randomUUID())), stringFactory2, 0); factoryCalls1.set(10); factoryCalls2.set(20); @@ -148,9 +149,9 @@ public final class UpdateDescriptionTest { AtomicInteger factoryCalls2 = new AtomicInteger(); UpdateDescription.StringFactory stringFactory1 = () -> "update." + factoryCalls1.incrementAndGet(); UpdateDescription.StringFactory stringFactory2 = () -> "update." + factoryCalls2.incrementAndGet(); - UpdateDescription description1 = UpdateDescription.mentioning(Collections.singletonList(UUID.randomUUID()), stringFactory1, 0); + UpdateDescription description1 = UpdateDescription.mentioning(Collections.singletonList(ACI.from(UUID.randomUUID())), stringFactory1, 0); UpdateDescription description2 = UpdateDescription.staticDescription("static", 0); - UpdateDescription description3 = UpdateDescription.mentioning(Collections.singletonList(UUID.randomUUID()), stringFactory2, 0); + UpdateDescription description3 = UpdateDescription.mentioning(Collections.singletonList(ACI.from(UUID.randomUUID())), stringFactory2, 0); factoryCalls1.set(100); factoryCalls2.set(200); diff --git a/app/src/test/java/org/thoughtcrime/securesms/groups/v2/ProfileKeySetTest.java b/app/src/test/java/org/thoughtcrime/securesms/groups/v2/ProfileKeySetTest.java index 068c2551b0..bc8379da51 100644 --- a/app/src/test/java/org/thoughtcrime/securesms/groups/v2/ProfileKeySetTest.java +++ b/app/src/test/java/org/thoughtcrime/securesms/groups/v2/ProfileKeySetTest.java @@ -5,6 +5,7 @@ import org.signal.core.util.logging.Log; import org.signal.zkgroup.profiles.ProfileKey; import org.thoughtcrime.securesms.crypto.ProfileKeyUtil; import org.thoughtcrime.securesms.testutil.LogRecorder; +import org.whispersystems.signalservice.api.push.ACI; import java.util.Collections; import java.util.UUID; @@ -39,7 +40,7 @@ public final class ProfileKeySetTest { profileKeySet.addKeysFromGroupChange(changeBy(editor).addMember(newMember, profileKey).build()); assertTrue(profileKeySet.getAuthoritativeProfileKeys().isEmpty()); - assertThat(profileKeySet.getProfileKeys(), is(Collections.singletonMap(newMember, profileKey))); + assertThat(profileKeySet.getProfileKeys(), is(Collections.singletonMap(ACI.from(newMember), profileKey))); } @Test @@ -51,7 +52,7 @@ public final class ProfileKeySetTest { profileKeySet.addKeysFromGroupChange(changeBy(newMember).addMember(newMember, profileKey).build()); assertTrue(profileKeySet.getProfileKeys().isEmpty()); - assertThat(profileKeySet.getAuthoritativeProfileKeys(), is(Collections.singletonMap(newMember, profileKey))); + assertThat(profileKeySet.getAuthoritativeProfileKeys(), is(Collections.singletonMap(ACI.from(newMember), profileKey))); } @Test @@ -63,7 +64,7 @@ public final class ProfileKeySetTest { profileKeySet.addKeysFromGroupChange(changeBy(newMember).promote(newMember, profileKey).build()); assertTrue(profileKeySet.getProfileKeys().isEmpty()); - assertThat(profileKeySet.getAuthoritativeProfileKeys(), is(Collections.singletonMap(newMember, profileKey))); + assertThat(profileKeySet.getAuthoritativeProfileKeys(), is(Collections.singletonMap(ACI.from(newMember), profileKey))); } @Test @@ -76,7 +77,7 @@ public final class ProfileKeySetTest { profileKeySet.addKeysFromGroupChange(changeBy(editor).promote(newMember, profileKey).build()); assertTrue(profileKeySet.getAuthoritativeProfileKeys().isEmpty()); - assertThat(profileKeySet.getProfileKeys(), is(Collections.singletonMap(newMember, profileKey))); + assertThat(profileKeySet.getProfileKeys(), is(Collections.singletonMap(ACI.from(newMember), profileKey))); } @Test @@ -88,7 +89,7 @@ public final class ProfileKeySetTest { profileKeySet.addKeysFromGroupChange(changeByUnknown().promote(newMember, profileKey).build()); assertTrue(profileKeySet.getAuthoritativeProfileKeys().isEmpty()); - assertThat(profileKeySet.getProfileKeys(), is(Collections.singletonMap(newMember, profileKey))); + assertThat(profileKeySet.getProfileKeys(), is(Collections.singletonMap(ACI.from(newMember), profileKey))); } @Test @@ -100,7 +101,7 @@ public final class ProfileKeySetTest { profileKeySet.addKeysFromGroupChange(changeBy(member).profileKeyUpdate(member, profileKey).build()); assertTrue(profileKeySet.getProfileKeys().isEmpty()); - assertThat(profileKeySet.getAuthoritativeProfileKeys(), is(Collections.singletonMap(member, profileKey))); + assertThat(profileKeySet.getAuthoritativeProfileKeys(), is(Collections.singletonMap(ACI.from(member), profileKey))); } @Test @@ -113,7 +114,7 @@ public final class ProfileKeySetTest { profileKeySet.addKeysFromGroupChange(changeBy(editor).profileKeyUpdate(member, profileKey).build()); assertTrue(profileKeySet.getAuthoritativeProfileKeys().isEmpty()); - assertThat(profileKeySet.getProfileKeys(), is(Collections.singletonMap(member, profileKey))); + assertThat(profileKeySet.getProfileKeys(), is(Collections.singletonMap(ACI.from(member), profileKey))); } @Test @@ -128,7 +129,7 @@ public final class ProfileKeySetTest { profileKeySet.addKeysFromGroupChange(changeBy(editor).profileKeyUpdate(member, profileKey2).build()); assertTrue(profileKeySet.getAuthoritativeProfileKeys().isEmpty()); - assertThat(profileKeySet.getProfileKeys(), is(Collections.singletonMap(member, profileKey2))); + assertThat(profileKeySet.getProfileKeys(), is(Collections.singletonMap(ACI.from(member), profileKey2))); } @Test @@ -143,7 +144,7 @@ public final class ProfileKeySetTest { profileKeySet.addKeysFromGroupChange(changeBy(editor).profileKeyUpdate(member, profileKey2).build()); assertTrue(profileKeySet.getProfileKeys().isEmpty()); - assertThat(profileKeySet.getAuthoritativeProfileKeys(), is(Collections.singletonMap(member, profileKey1))); + assertThat(profileKeySet.getAuthoritativeProfileKeys(), is(Collections.singletonMap(ACI.from(member), profileKey1))); } @Test @@ -158,7 +159,7 @@ public final class ProfileKeySetTest { profileKeySet.addKeysFromGroupChange(changeBy(member).profileKeyUpdate(member, profileKey2).build()); assertTrue(profileKeySet.getProfileKeys().isEmpty()); - assertThat(profileKeySet.getAuthoritativeProfileKeys(), is(Collections.singletonMap(member, profileKey2))); + assertThat(profileKeySet.getAuthoritativeProfileKeys(), is(Collections.singletonMap(ACI.from(member), profileKey2))); } @Test @@ -185,7 +186,7 @@ public final class ProfileKeySetTest { profileKeySet.addKeysFromGroupChange(changeBy(editor).requestJoin(profileKey).build()); - assertThat(profileKeySet.getAuthoritativeProfileKeys(), is(Collections.singletonMap(editor, profileKey))); + assertThat(profileKeySet.getAuthoritativeProfileKeys(), is(Collections.singletonMap(ACI.from(editor), profileKey))); assertTrue(profileKeySet.getProfileKeys().isEmpty()); } @@ -199,6 +200,6 @@ public final class ProfileKeySetTest { profileKeySet.addKeysFromGroupChange(changeBy(editor).requestJoin(requesting, profileKey).build()); assertTrue(profileKeySet.getAuthoritativeProfileKeys().isEmpty()); - assertThat(profileKeySet.getProfileKeys(), is(Collections.singletonMap(requesting, profileKey))); + assertThat(profileKeySet.getProfileKeys(), is(Collections.singletonMap(ACI.from(requesting), profileKey))); } } diff --git a/app/src/test/java/org/thoughtcrime/securesms/recipients/RecipientIdCacheTest.java b/app/src/test/java/org/thoughtcrime/securesms/recipients/RecipientIdCacheTest.java index b8aa0e39ab..f888a37696 100644 --- a/app/src/test/java/org/thoughtcrime/securesms/recipients/RecipientIdCacheTest.java +++ b/app/src/test/java/org/thoughtcrime/securesms/recipients/RecipientIdCacheTest.java @@ -8,6 +8,7 @@ import org.junit.Test; import org.signal.core.util.logging.Log; import org.thoughtcrime.securesms.testutil.LogRecorder; import org.whispersystems.libsignal.util.guava.Optional; +import org.whispersystems.signalservice.api.push.ACI; import java.util.UUID; @@ -39,7 +40,7 @@ public final class RecipientIdCacheTest { @Test public void empty_access_by_uuid() { - RecipientId recipientId = recipientIdCache.get(UUID.randomUUID(), null); + RecipientId recipientId = recipientIdCache.get(ACI.from(UUID.randomUUID()), null); assertNull(recipientId); } @@ -54,11 +55,11 @@ public final class RecipientIdCacheTest { @Test public void cache_hit_by_uuid() { RecipientId recipientId1 = recipientId(); - UUID uuid1 = UUID.randomUUID(); + ACI aci1 = ACI.from(UUID.randomUUID()); - recipientIdCache.put(recipient(recipientId1, uuid1, null)); + recipientIdCache.put(recipient(recipientId1, aci1, null)); - RecipientId recipientId = recipientIdCache.get(uuid1, null); + RecipientId recipientId = recipientIdCache.get(aci1, null); assertEquals(recipientId1, recipientId); } @@ -66,12 +67,12 @@ public final class RecipientIdCacheTest { @Test public void cache_miss_by_uuid() { RecipientId recipientId1 = recipientId(); - UUID uuid1 = UUID.randomUUID(); - UUID uuid2 = UUID.randomUUID(); + ACI aci1 = ACI.from(UUID.randomUUID()); + ACI aci2 = ACI.from(UUID.randomUUID()); - recipientIdCache.put(recipient(recipientId1, uuid1, null)); + recipientIdCache.put(recipient(recipientId1, aci1, null)); - RecipientId recipientId = recipientIdCache.get(uuid2, null); + RecipientId recipientId = recipientIdCache.get(aci2, null); assertNull(recipientId); } @@ -79,11 +80,11 @@ public final class RecipientIdCacheTest { @Test public void cache_hit_by_uuid_e164_not_supplied_on_get() { RecipientId recipientId1 = recipientId(); - UUID uuid1 = UUID.randomUUID(); + ACI aci1 = ACI.from(UUID.randomUUID()); - recipientIdCache.put(recipient(recipientId1, uuid1, "+15551234567")); + recipientIdCache.put(recipient(recipientId1, aci1, "+15551234567")); - RecipientId recipientId = recipientIdCache.get(uuid1, null); + RecipientId recipientId = recipientIdCache.get(aci1, null); assertEquals(recipientId1, recipientId); } @@ -91,11 +92,11 @@ public final class RecipientIdCacheTest { @Test public void cache_miss_by_uuid_e164_not_supplied_on_put() { RecipientId recipientId1 = recipientId(); - UUID uuid1 = UUID.randomUUID(); + ACI aci1 = ACI.from(UUID.randomUUID()); - recipientIdCache.put(recipient(recipientId1, uuid1, null)); + recipientIdCache.put(recipient(recipientId1, aci1, null)); - RecipientId recipientId = recipientIdCache.get(uuid1, "+15551234567"); + RecipientId recipientId = recipientIdCache.get(aci1, "+15551234567"); assertNull(recipientId); } @@ -128,9 +129,9 @@ public final class RecipientIdCacheTest { @Test public void cache_hit_by_e164_uuid_not_supplied_on_get() { RecipientId recipientId1 = recipientId(); - UUID uuid1 = UUID.randomUUID(); + ACI aci1 = ACI.from(UUID.randomUUID()); - recipientIdCache.put(recipient(recipientId1, uuid1, "+15551234567")); + recipientIdCache.put(recipient(recipientId1, aci1, "+15551234567")); RecipientId recipientId = recipientIdCache.get(null, "+15551234567"); @@ -140,12 +141,12 @@ public final class RecipientIdCacheTest { @Test public void cache_miss_by_e164_uuid_not_supplied_on_put() { RecipientId recipientId1 = recipientId(); - UUID uuid1 = UUID.randomUUID(); + ACI aci1 = ACI.from(UUID.randomUUID()); String e164 = "+1555123456"; recipientIdCache.put(recipient(recipientId1, null, e164)); - RecipientId recipientId = recipientIdCache.get(uuid1, e164); + RecipientId recipientId = recipientIdCache.get(aci1, e164); assertNull(recipientId); } @@ -153,12 +154,12 @@ public final class RecipientIdCacheTest { @Test public void cache_hit_by_both() { RecipientId recipientId1 = recipientId(); - UUID uuid1 = UUID.randomUUID(); + ACI aci1 = ACI.from(UUID.randomUUID()); String e164 = "+1555123456"; - recipientIdCache.put(recipient(recipientId1, uuid1, e164)); + recipientIdCache.put(recipient(recipientId1, aci1, e164)); - RecipientId recipientId = recipientIdCache.get(uuid1, e164); + RecipientId recipientId = recipientIdCache.get(aci1, e164); assertEquals(recipientId1, recipientId); } @@ -166,13 +167,13 @@ public final class RecipientIdCacheTest { @Test public void full_recipient_id_learned_by_two_puts() { RecipientId recipientId1 = recipientId(); - UUID uuid1 = UUID.randomUUID(); + ACI aci1 = ACI.from(UUID.randomUUID()); String e164 = "+1555123456"; - recipientIdCache.put(recipient(recipientId1, uuid1, null)); + recipientIdCache.put(recipient(recipientId1, aci1, null)); recipientIdCache.put(recipient(recipientId1, null, e164)); - RecipientId recipientId = recipientIdCache.get(uuid1, e164); + RecipientId recipientId = recipientIdCache.get(aci1, e164); assertEquals(recipientId1, recipientId); } @@ -181,13 +182,13 @@ public final class RecipientIdCacheTest { public void if_cache_state_disagrees_returns_null() { RecipientId recipientId1 = recipientId(); RecipientId recipientId2 = recipientId(); - UUID uuid = UUID.randomUUID(); + ACI aci = ACI.from(UUID.randomUUID()); String e164 = "+1555123456"; recipientIdCache.put(recipient(recipientId1, null, e164)); - recipientIdCache.put(recipient(recipientId2, uuid, null)); + recipientIdCache.put(recipient(recipientId2, aci, null)); - RecipientId recipientId = recipientIdCache.get(uuid, e164); + RecipientId recipientId = recipientIdCache.get(aci, e164); assertNull(recipientId); @@ -199,15 +200,15 @@ public final class RecipientIdCacheTest { public void after_invalid_cache_hit_entries_are_cleared_up() { RecipientId recipientId1 = recipientId(); RecipientId recipientId2 = recipientId(); - UUID uuid = UUID.randomUUID(); + ACI aci = ACI.from(UUID.randomUUID()); String e164 = "+1555123456"; recipientIdCache.put(recipient(recipientId1, null, e164)); - recipientIdCache.put(recipient(recipientId2, uuid, null)); + recipientIdCache.put(recipient(recipientId2, aci, null)); - recipientIdCache.get(uuid, e164); + recipientIdCache.get(aci, e164); - assertNull(recipientIdCache.get(uuid, null)); + assertNull(recipientIdCache.get(aci, null)); assertNull(recipientIdCache.get(null, e164)); } @@ -215,57 +216,57 @@ public final class RecipientIdCacheTest { public void multiple_entries() { RecipientId recipientId1 = recipientId(); RecipientId recipientId2 = recipientId(); - UUID uuid1 = UUID.randomUUID(); - UUID uuid2 = UUID.randomUUID(); + ACI aci1 = ACI.from(UUID.randomUUID()); + ACI aci2 = ACI.from(UUID.randomUUID()); - recipientIdCache.put(recipient(recipientId1, uuid1, null)); - recipientIdCache.put(recipient(recipientId2, uuid2, null)); + recipientIdCache.put(recipient(recipientId1, aci1, null)); + recipientIdCache.put(recipient(recipientId2, aci2, null)); - assertEquals(recipientId1, recipientIdCache.get(uuid1, null)); - assertEquals(recipientId2, recipientIdCache.get(uuid2, null)); + assertEquals(recipientId1, recipientIdCache.get(aci1, null)); + assertEquals(recipientId2, recipientIdCache.get(aci2, null)); } @Test public void drops_oldest_when_reaches_cache_limit() { RecipientId recipientId1 = recipientId(); - UUID uuid1 = UUID.randomUUID(); + ACI aci1 = ACI.from(UUID.randomUUID()); - recipientIdCache.put(recipient(recipientId1, uuid1, null)); + recipientIdCache.put(recipient(recipientId1, aci1, null)); for (int i = 0; i < TEST_CACHE_LIMIT; i++) { - recipientIdCache.put(recipient(recipientId(), UUID.randomUUID(), null)); + recipientIdCache.put(recipient(recipientId(), ACI.from(UUID.randomUUID()), null)); } - assertNull(recipientIdCache.get(uuid1, null)); + assertNull(recipientIdCache.get(aci1, null)); } @Test public void remains_in_cache_when_used_before_reaching_cache_limit() { RecipientId recipientId1 = recipientId(); - UUID uuid1 = UUID.randomUUID(); + ACI aci1 = ACI.from(UUID.randomUUID()); - recipientIdCache.put(recipient(recipientId1, uuid1, null)); + recipientIdCache.put(recipient(recipientId1, aci1, null)); for (int i = 0; i < TEST_CACHE_LIMIT - 1; i++) { - recipientIdCache.put(recipient(recipientId(), UUID.randomUUID(), null)); + recipientIdCache.put(recipient(recipientId(), ACI.from(UUID.randomUUID()), null)); } - assertEquals(recipientId1, recipientIdCache.get(uuid1, null)); + assertEquals(recipientId1, recipientIdCache.get(aci1, null)); - recipientIdCache.put(recipient(recipientId(), UUID.randomUUID(), null)); + recipientIdCache.put(recipient(recipientId(), ACI.from(UUID.randomUUID()), null)); - assertEquals(recipientId1, recipientIdCache.get(uuid1, null)); + assertEquals(recipientId1, recipientIdCache.get(aci1, null)); } private static @NonNull RecipientId recipientId() { return mock(RecipientId.class); } - private static @NonNull Recipient recipient(RecipientId recipientId, @Nullable UUID uuid, @Nullable String e164) { + private static @NonNull Recipient recipient(RecipientId recipientId, @Nullable ACI aci, @Nullable String e164) { Recipient mock = mock(Recipient.class); when(mock.getId()).thenReturn(recipientId); - when(mock.getUuid()).thenReturn(Optional.fromNullable(uuid)); + when(mock.getAci()).thenReturn(Optional.fromNullable(aci)); when(mock.getE164()).thenReturn(Optional.fromNullable(e164)); return mock; diff --git a/app/src/test/java/org/thoughtcrime/securesms/storage/StorageSyncHelperTest.java b/app/src/test/java/org/thoughtcrime/securesms/storage/StorageSyncHelperTest.java index 963592f17c..ce7704c66f 100644 --- a/app/src/test/java/org/thoughtcrime/securesms/storage/StorageSyncHelperTest.java +++ b/app/src/test/java/org/thoughtcrime/securesms/storage/StorageSyncHelperTest.java @@ -1,7 +1,5 @@ package org.thoughtcrime.securesms.storage; -import androidx.annotation.NonNull; - import com.annimon.stream.Stream; import org.junit.Before; @@ -17,6 +15,7 @@ import org.thoughtcrime.securesms.recipients.Recipient; import org.thoughtcrime.securesms.storage.StorageSyncHelper.IdDifferenceResult; import org.thoughtcrime.securesms.util.FeatureFlags; import org.whispersystems.libsignal.util.guava.Optional; +import org.whispersystems.signalservice.api.push.ACI; import org.whispersystems.signalservice.api.push.SignalServiceAddress; import org.whispersystems.signalservice.api.storage.SignalAccountRecord; import org.whispersystems.signalservice.api.storage.SignalContactRecord; @@ -25,7 +24,6 @@ import org.whispersystems.signalservice.api.storage.SignalGroupV2Record; import org.whispersystems.signalservice.api.storage.SignalRecord; import org.whispersystems.signalservice.api.storage.SignalStorageRecord; import org.whispersystems.signalservice.api.storage.StorageId; -import org.whispersystems.signalservice.api.util.UuidUtil; import java.util.Arrays; import java.util.HashMap; @@ -33,7 +31,6 @@ import java.util.LinkedHashSet; import java.util.List; import java.util.Map; import java.util.Set; -import java.util.UUID; import static junit.framework.TestCase.assertTrue; import static org.junit.Assert.assertEquals; @@ -52,23 +49,15 @@ import static org.thoughtcrime.securesms.testutil.TestHelpers.byteListOf; @PowerMockRunnerDelegate(JUnit4.class) public final class StorageSyncHelperTest { - private static final UUID UUID_A = UuidUtil.parseOrThrow("ebef429e-695e-4f51-bcc4-526a60ac68c7"); - private static final UUID UUID_B = UuidUtil.parseOrThrow("32119989-77fb-4e18-af70-81d55185c6b1"); - private static final UUID UUID_C = UuidUtil.parseOrThrow("b5552203-2bca-44aa-b6f5-9f5d87a335b6"); - private static final UUID UUID_D = UuidUtil.parseOrThrow("94829a32-7199-4a7b-8fb4-7e978509ab84"); - private static final UUID UUID_SELF = UuidUtil.parseOrThrow("1b2a2ca5-fc9e-4656-8c9f-22cc349ed3af"); + private static final ACI ACI_A = ACI.parseOrThrow("ebef429e-695e-4f51-bcc4-526a60ac68c7"); + private static final ACI ACI_SELF = ACI.parseOrThrow("1b2a2ca5-fc9e-4656-8c9f-22cc349ed3af"); private static final String E164_A = "+16108675309"; - private static final String E164_B = "+16101234567"; - private static final String E164_C = "+16101112222"; - private static final String E164_D = "+16103334444"; private static final String E164_SELF = "+16105555555"; - private static final int UNKNOWN_TYPE = Integer.MAX_VALUE; - private static final Recipient SELF = mock(Recipient.class); static { - when(SELF.getUuid()).thenReturn(Optional.of(UUID_SELF)); + when(SELF.getAci()).thenReturn(Optional.of(ACI_SELF)); when(SELF.getE164()).thenReturn(Optional.of(E164_SELF)); when(SELF.resolve()).thenReturn(SELF); } @@ -145,8 +134,8 @@ public final class StorageSyncHelperTest { byte[] profileKey = new byte[32]; byte[] profileKeyCopy = profileKey.clone(); - SignalContactRecord a = contactBuilder(1, UUID_A, E164_A, "a").setProfileKey(profileKey).build(); - SignalContactRecord b = contactBuilder(1, UUID_A, E164_A, "a").setProfileKey(profileKeyCopy).build(); + SignalContactRecord a = contactBuilder(1, ACI_A, E164_A, "a").setProfileKey(profileKey).build(); + SignalContactRecord b = contactBuilder(1, ACI_A, E164_A, "a").setProfileKey(profileKeyCopy).build(); assertEquals(a, b); assertEquals(a.hashCode(), b.hashCode()); @@ -160,8 +149,8 @@ public final class StorageSyncHelperTest { byte[] profileKeyCopy = profileKey.clone(); profileKeyCopy[0] = 1; - SignalContactRecord a = contactBuilder(1, UUID_A, E164_A, "a").setProfileKey(profileKey).build(); - SignalContactRecord b = contactBuilder(1, UUID_A, E164_A, "a").setProfileKey(profileKeyCopy).build(); + SignalContactRecord a = contactBuilder(1, ACI_A, E164_A, "a").setProfileKey(profileKey).build(); + SignalContactRecord b = contactBuilder(1, ACI_A, E164_A, "a").setProfileKey(profileKeyCopy).build(); assertNotEquals(a, b); assertNotEquals(a.hashCode(), b.hashCode()); @@ -169,16 +158,6 @@ public final class StorageSyncHelperTest { assertTrue(StorageSyncHelper.profileKeyChanged(update(a, b))); } - private static Set recordSetOf(SignalRecord... records) { - LinkedHashSet storageRecords = new LinkedHashSet<>(); - - for (SignalRecord record : records) { - storageRecords.add(record(record)); - } - - return storageRecords; - } - private static SignalStorageRecord record(SignalRecord record) { if (record instanceof SignalContactRecord) { return SignalStorageRecord.forContact(record.getId(), (SignalContactRecord) record); @@ -194,50 +173,18 @@ public final class StorageSyncHelperTest { } private static SignalContactRecord.Builder contactBuilder(int key, - UUID uuid, + ACI aci, String e164, String profileName) { - return new SignalContactRecord.Builder(byteArray(key), new SignalServiceAddress(uuid, e164)) + return new SignalContactRecord.Builder(byteArray(key), new SignalServiceAddress(aci, e164)) .setGivenName(profileName); } - private static SignalContactRecord contact(int key, - UUID uuid, - String e164, - String profileName) - { - return contactBuilder(key, uuid, e164, profileName).build(); - } - - private static SignalGroupV1Record groupV1(int key, - int groupId, - boolean blocked, - boolean profileSharing) - { - return new SignalGroupV1Record.Builder(byteArray(key), byteArray(groupId, 16)).setBlocked(blocked).setProfileSharingEnabled(profileSharing).build(); - } - - private static SignalGroupV2Record groupV2(int key, - int groupId, - boolean blocked, - boolean profileSharing) - { - return new SignalGroupV2Record.Builder(byteArray(key), byteArray(groupId, 32)).setBlocked(blocked).setProfileSharingEnabled(profileSharing).build(); - } - private static StorageRecordUpdate update(E oldRecord, E newRecord) { return new StorageRecordUpdate<>(oldRecord, newRecord); } - private static StorageRecordUpdate recordUpdate(E oldContact, E newContact) { - return new StorageRecordUpdate<>(record(oldContact), record(newContact)); - } - - private static SignalStorageRecord unknown(int key) { - return SignalStorageRecord.forUnknown(StorageId.forType(byteArray(key), UNKNOWN_TYPE)); - } - private static List keyListOf(int... vals) { return Stream.of(byteListOf(vals)).map(b -> StorageId.forType(b, 1)).toList(); } @@ -245,35 +192,4 @@ public final class StorageSyncHelperTest { private static List keyListOf(Map vals) { return Stream.of(vals).map(e -> StorageId.forType(byteArray(e.getKey()), e.getValue())).toList(); } - - private static StorageId contactKey(int val) { - return StorageId.forContact(byteArray(val)); - } - - private static StorageId groupV1Key(int val) { - return StorageId.forGroupV1(byteArray(val)); - } - - private static StorageId groupV2Key(int val) { - return StorageId.forGroupV2(byteArray(val)); - } - - private static StorageId unknownKey(int val) { - return StorageId.forType(byteArray(val), UNKNOWN_TYPE); - } - - private static class TestGenerator implements StorageKeyGenerator { - private final int[] keys; - - private int index = 0; - - private TestGenerator(int... keys) { - this.keys = keys; - } - - @Override - public @NonNull byte[] generate() { - return byteArray(keys[index++]); - } - } } diff --git a/libsignal/service/src/main/java/org/whispersystems/signalservice/api/SignalServiceAccountManager.java b/libsignal/service/src/main/java/org/whispersystems/signalservice/api/SignalServiceAccountManager.java index 0ecf00e7a8..3651671609 100644 --- a/libsignal/service/src/main/java/org/whispersystems/signalservice/api/SignalServiceAccountManager.java +++ b/libsignal/service/src/main/java/org/whispersystems/signalservice/api/SignalServiceAccountManager.java @@ -32,6 +32,7 @@ import org.whispersystems.signalservice.api.messages.multidevice.DeviceInfo; import org.whispersystems.signalservice.api.payments.CurrencyConversions; import org.whispersystems.signalservice.api.profiles.ProfileAndCredential; import org.whispersystems.signalservice.api.profiles.SignalServiceProfileWrite; +import org.whispersystems.signalservice.api.push.ACI; import org.whispersystems.signalservice.api.push.ContactTokenDetails; import org.whispersystems.signalservice.api.push.SignedPreKeyEntity; import org.whispersystems.signalservice.api.push.exceptions.NoContentException; @@ -121,19 +122,21 @@ public class SignalServiceAccountManager { /** * Construct a SignalServiceAccountManager. - * - * @param configuration The URL for the Signal Service. - * @param uuid The Signal Service UUID. + * @param configuration The URL for the Signal Service. + * @param aci The Signal Service UUID. * @param e164 The Signal Service phone number. * @param password A Signal Service password. * @param signalAgent A string which identifies the client software. */ public SignalServiceAccountManager(SignalServiceConfiguration configuration, - UUID uuid, String e164, String password, - String signalAgent, boolean automaticNetworkRetry) + ACI aci, + String e164, + String password, + String signalAgent, + boolean automaticNetworkRetry) { this(configuration, - new StaticCredentialsProvider(uuid, e164, password), + new StaticCredentialsProvider(aci, e164, password), signalAgent, new GroupsV2Operations(ClientZkOperations.create(configuration)), automaticNetworkRetry); @@ -171,8 +174,8 @@ public class SignalServiceAccountManager { this.pushServiceSocket.removeRegistrationLockV1(); } - public UUID getOwnUuid() throws IOException { - return this.pushServiceSocket.getOwnUuid(); + public ACI getOwnAci() throws IOException { + return this.pushServiceSocket.getOwnAci(); } public WhoAmIResponse getWhoAmI() throws IOException { @@ -443,7 +446,7 @@ public class SignalServiceAccountManager { } @SuppressWarnings("SameParameterValue") - public Map getRegisteredUsers(KeyStore iasKeyStore, Set e164numbers, String mrenclave) + public Map getRegisteredUsers(KeyStore iasKeyStore, Set e164numbers, String mrenclave) throws IOException, Quote.InvalidQuoteFormatException, UnauthenticatedQuoteException, SignatureException, UnauthenticatedResponseException, InvalidKeyException { if (e164numbers.isEmpty()) { @@ -470,14 +473,14 @@ public class SignalServiceAccountManager { DiscoveryResponse response = this.pushServiceSocket.getContactDiscoveryRegisteredUsers(authorization, request, cookies, mrenclave); byte[] data = ContactDiscoveryCipher.getDiscoveryResponseData(response, attestations.values()); - HashMap results = new HashMap<>(addressBook.size()); - DataInputStream uuidInputStream = new DataInputStream(new ByteArrayInputStream(data)); + HashMap results = new HashMap<>(addressBook.size()); + DataInputStream uuidInputStream = new DataInputStream(new ByteArrayInputStream(data)); for (String candidate : addressBook) { long candidateUuidHigh = uuidInputStream.readLong(); long candidateUuidLow = uuidInputStream.readLong(); if (candidateUuidHigh != 0 || candidateUuidLow != 0) { - results.put('+' + candidate, new UUID(candidateUuidHigh, candidateUuidLow)); + results.put('+' + candidate, ACI.from(new UUID(candidateUuidHigh, candidateUuidLow))); } } @@ -487,13 +490,13 @@ public class SignalServiceAccountManager { } } - public Map getRegisteredUsersWithCdsh(Set e164numbers, String hexPublicKey, String hexCodeHash) + public Map getRegisteredUsersWithCdsh(Set e164numbers, String hexPublicKey, String hexCodeHash) throws IOException { - CdshService service = new CdshService(configuration, hexPublicKey, hexCodeHash); - Single>> result = service.getRegisteredUsers(e164numbers); + CdshService service = new CdshService(configuration, hexPublicKey, hexCodeHash); + Single>> result = service.getRegisteredUsers(e164numbers); - ServiceResponse> response; + ServiceResponse> response; try { response = result.blockingGet(); } catch (Exception e) { @@ -698,7 +701,7 @@ public class SignalServiceAccountManager { .setProvisioningVersion(ProvisioningVersion.CURRENT_VALUE); String e164 = credentials.getE164(); - UUID uuid = credentials.getUuid(); + ACI aci = credentials.getAci(); if (e164 != null) { message.setNumber(e164); @@ -706,8 +709,8 @@ public class SignalServiceAccountManager { throw new AssertionError("Missing phone number!"); } - if (uuid != null) { - message.setUuid(uuid.toString()); + if (aci != null) { + message.setUuid(aci.toString()); } else { Log.w(TAG, "[addDevice] Missing UUID."); } @@ -747,7 +750,7 @@ public class SignalServiceAccountManager { /** * @return The avatar URL path, if one was written. */ - public Optional setVersionedProfile(UUID uuid, + public Optional setVersionedProfile(ACI aci, ProfileKey profileKey, String name, String about, @@ -774,22 +777,22 @@ public class SignalServiceAccountManager { new ProfileCipherOutputStreamFactory(profileKey)); } - return this.pushServiceSocket.writeProfile(new SignalServiceProfileWrite(profileKey.getProfileKeyVersion(uuid).serialize(), + return this.pushServiceSocket.writeProfile(new SignalServiceProfileWrite(profileKey.getProfileKeyVersion(aci.uuid()).serialize(), ciphertextName, ciphertextAbout, ciphertextEmoji, ciphertextMobileCoinAddress, hasAvatar, - profileKey.getCommitment(uuid).serialize(), + profileKey.getCommitment(aci.uuid()).serialize(), visibleBadgeIds), profileAvatarData); } - public Optional resolveProfileKeyCredential(UUID uuid, ProfileKey profileKey, Locale locale) + public Optional resolveProfileKeyCredential(ACI aci, ProfileKey profileKey, Locale locale) throws NonSuccessfulResponseCodeException, PushNetworkException { try { - ProfileAndCredential credential = this.pushServiceSocket.retrieveVersionedProfileAndCredential(uuid, profileKey, Optional.absent(), locale).get(10, TimeUnit.SECONDS); + ProfileAndCredential credential = this.pushServiceSocket.retrieveVersionedProfileAndCredential(aci.uuid(), profileKey, Optional.absent(), locale).get(10, TimeUnit.SECONDS); return credential.getProfileKeyCredential(); } catch (InterruptedException | TimeoutException e) { throw new PushNetworkException(e); diff --git a/libsignal/service/src/main/java/org/whispersystems/signalservice/api/SignalServiceMessageReceiver.java b/libsignal/service/src/main/java/org/whispersystems/signalservice/api/SignalServiceMessageReceiver.java index f16862923d..e706e4601c 100644 --- a/libsignal/service/src/main/java/org/whispersystems/signalservice/api/SignalServiceMessageReceiver.java +++ b/libsignal/service/src/main/java/org/whispersystems/signalservice/api/SignalServiceMessageReceiver.java @@ -20,6 +20,7 @@ import org.whispersystems.signalservice.api.messages.SignalServiceEnvelope; import org.whispersystems.signalservice.api.messages.SignalServiceStickerManifest; import org.whispersystems.signalservice.api.profiles.ProfileAndCredential; import org.whispersystems.signalservice.api.profiles.SignalServiceProfile; +import org.whispersystems.signalservice.api.push.ACI; import org.whispersystems.signalservice.api.push.SignalServiceAddress; import org.whispersystems.signalservice.api.push.exceptions.MissingConfigurationException; import org.whispersystems.signalservice.api.util.CredentialsProvider; @@ -90,13 +91,13 @@ public class SignalServiceMessageReceiver { SignalServiceProfile.RequestType requestType, Locale locale) { - UUID uuid = address.getUuid(); + ACI aci = address.getAci(); if (profileKey.isPresent()) { if (requestType == SignalServiceProfile.RequestType.PROFILE_AND_CREDENTIAL) { - return socket.retrieveVersionedProfileAndCredential(uuid, profileKey.get(), unidentifiedAccess, locale); + return socket.retrieveVersionedProfileAndCredential(aci.uuid(), profileKey.get(), unidentifiedAccess, locale); } else { - return FutureTransformers.map(socket.retrieveVersionedProfile(uuid, profileKey.get(), unidentifiedAccess, locale), profile -> { + return FutureTransformers.map(socket.retrieveVersionedProfile(aci.uuid(), profileKey.get(), unidentifiedAccess, locale), profile -> { return new ProfileAndCredential(profile, SignalServiceProfile.RequestType.PROFILE, Optional.absent()); @@ -204,7 +205,7 @@ public class SignalServiceMessageReceiver { SignalServiceEnvelope envelope; if (entity.hasSource() && entity.getSourceDevice() > 0) { - SignalServiceAddress address = new SignalServiceAddress(UuidUtil.parseOrThrow(entity.getSourceUuid()), entity.getSourceE164()); + SignalServiceAddress address = new SignalServiceAddress(ACI.parseOrThrow(entity.getSourceUuid()), entity.getSourceE164()); envelope = new SignalServiceEnvelope(entity.getType(), Optional.of(address), entity.getSourceDevice(), 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 b73b1c7402..ee2e3b08dd 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 @@ -62,6 +62,7 @@ import org.whispersystems.signalservice.api.messages.multidevice.VerifiedMessage import org.whispersystems.signalservice.api.messages.multidevice.ViewOnceOpenMessage; import org.whispersystems.signalservice.api.messages.multidevice.ViewedMessage; import org.whispersystems.signalservice.api.messages.shared.SharedContact; +import org.whispersystems.signalservice.api.push.ACI; import org.whispersystems.signalservice.api.push.DistributionId; import org.whispersystems.signalservice.api.push.SignalServiceAddress; import org.whispersystems.signalservice.api.push.exceptions.AuthorizationFailedException; @@ -76,7 +77,6 @@ import org.whispersystems.signalservice.api.services.MessagingService; import org.whispersystems.signalservice.api.util.CredentialsProvider; import org.whispersystems.signalservice.api.util.Uint64RangeException; import org.whispersystems.signalservice.api.util.Uint64Util; -import org.whispersystems.signalservice.api.util.UuidUtil; import org.whispersystems.signalservice.api.websocket.WebSocketUnavailableException; import org.whispersystems.signalservice.internal.configuration.SignalServiceConfiguration; import org.whispersystems.signalservice.internal.crypto.PaddingInputStream; @@ -128,7 +128,6 @@ import java.util.LinkedList; import java.util.List; import java.util.Map; import java.util.Set; -import java.util.UUID; import java.util.concurrent.ExecutionException; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; @@ -173,7 +172,7 @@ public class SignalServiceMessageSender { this.socket = new PushServiceSocket(urls, credentialsProvider, signalAgent, clientZkProfileOperations, automaticNetworkRetry); this.store = store; this.sessionLock = sessionLock; - this.localAddress = new SignalServiceAddress(credentialsProvider.getUuid(), credentialsProvider.getE164()); + this.localAddress = new SignalServiceAddress(credentialsProvider.getAci(), credentialsProvider.getE164()); this.attachmentService = new AttachmentService(signalWebSocket); this.messagingService = new MessagingService(signalWebSocket); this.eventListener = eventListener; @@ -773,14 +772,14 @@ public class SignalServiceMessageSender { DataMessage.Quote.Builder quoteBuilder = DataMessage.Quote.newBuilder() .setId(message.getQuote().get().getId()) .setText(message.getQuote().get().getText()) - .setAuthorUuid(message.getQuote().get().getAuthor().getUuid().toString()); + .setAuthorUuid(message.getQuote().get().getAuthor().getAci().toString()); if (!message.getQuote().get().getMentions().isEmpty()) { for (SignalServiceDataMessage.Mention mention : message.getQuote().get().getMentions()) { quoteBuilder.addBodyRanges(DataMessage.BodyRange.newBuilder() .setStart(mention.getStart()) .setLength(mention.getLength()) - .setMentionUuid(mention.getUuid().toString())); + .setMentionUuid(mention.getAci().toString())); } builder.setRequiredProtocolVersion(Math.max(DataMessage.ProtocolVersion.MENTIONS_VALUE, builder.getRequiredProtocolVersion())); @@ -834,7 +833,7 @@ public class SignalServiceMessageSender { builder.addBodyRanges(DataMessage.BodyRange.newBuilder() .setStart(mention.getStart()) .setLength(mention.getLength()) - .setMentionUuid(mention.getUuid().toString())); + .setMentionUuid(mention.getAci().toString())); } builder.setRequiredProtocolVersion(Math.max(DataMessage.ProtocolVersion.MENTIONS_VALUE, builder.getRequiredProtocolVersion())); } @@ -869,7 +868,7 @@ public class SignalServiceMessageSender { .setEmoji(message.getReaction().get().getEmoji()) .setRemove(message.getReaction().get().isRemove()) .setTargetSentTimestamp(message.getReaction().get().getTargetSentTimestamp()) - .setTargetAuthorUuid(message.getReaction().get().getTargetAuthor().getUuid().toString()); + .setTargetAuthorUuid(message.getReaction().get().getTargetAuthor().getAci().toString()); builder.setReaction(reactionBuilder.build()); builder.setRequiredProtocolVersion(Math.max(DataMessage.ProtocolVersion.REACTIONS_VALUE, builder.getRequiredProtocolVersion())); @@ -1041,7 +1040,7 @@ public class SignalServiceMessageSender { if (result.getSuccess() != null) { SyncMessage.Sent.UnidentifiedDeliveryStatus.Builder builder = SyncMessage.Sent.UnidentifiedDeliveryStatus.newBuilder(); - builder.setDestinationUuid(result.getAddress().getUuid().toString()); + builder.setDestinationUuid(result.getAddress().getAci().toString()); if (result.getAddress().getNumber().isPresent()) { builder.setDestinationE164(result.getAddress().getNumber().get()); @@ -1054,7 +1053,7 @@ public class SignalServiceMessageSender { } if (recipient.isPresent()) { - sentMessage.setDestinationUuid(recipient.get().getUuid().toString()); + sentMessage.setDestinationUuid(recipient.get().getAci().toString()); if (recipient.get().getNumber().isPresent()) { sentMessage.setDestinationE164(recipient.get().getNumber().get()); @@ -1082,7 +1081,7 @@ public class SignalServiceMessageSender { for (ReadMessage readMessage : readMessages) { SyncMessage.Read.Builder readBuilder = SyncMessage.Read.newBuilder().setTimestamp(readMessage.getTimestamp()); - readBuilder.setSenderUuid(readMessage.getSender().getUuid().toString()); + readBuilder.setSenderUuid(readMessage.getSender().getAci().toString()); if (readMessage.getSender().getNumber().isPresent()) { readBuilder.setSenderE164(readMessage.getSender().getNumber().get()); @@ -1101,7 +1100,7 @@ public class SignalServiceMessageSender { for (ViewedMessage readMessage : readMessages) { SyncMessage.Viewed.Builder viewedBuilder = SyncMessage.Viewed.newBuilder().setTimestamp(readMessage.getTimestamp()); - viewedBuilder.setSenderUuid(readMessage.getSender().getUuid().toString()); + viewedBuilder.setSenderUuid(readMessage.getSender().getAci().toString()); if (readMessage.getSender().getNumber().isPresent()) { viewedBuilder.setSenderE164(readMessage.getSender().getNumber().get()); @@ -1118,7 +1117,7 @@ public class SignalServiceMessageSender { SyncMessage.Builder builder = createSyncMessageBuilder(); SyncMessage.ViewOnceOpen.Builder viewOnceBuilder = SyncMessage.ViewOnceOpen.newBuilder().setTimestamp(readMessage.getTimestamp()); - viewOnceBuilder.setSenderUuid(readMessage.getSender().getUuid().toString()); + viewOnceBuilder.setSenderUuid(readMessage.getSender().getAci().toString()); if (readMessage.getSender().getNumber().isPresent()) { viewOnceBuilder.setSenderE164(readMessage.getSender().getNumber().get()); @@ -1135,7 +1134,7 @@ public class SignalServiceMessageSender { SyncMessage.Blocked.Builder blockedMessage = SyncMessage.Blocked.newBuilder(); for (SignalServiceAddress address : blocked.getAddresses()) { - blockedMessage.addUuids(address.getUuid().toString()); + blockedMessage.addUuids(address.getAci().toString()); if (address.getNumber().isPresent()) { blockedMessage.addNumbers(address.getNumber().get()); } @@ -1235,7 +1234,7 @@ public class SignalServiceMessageSender { if (message.getPerson().get().getNumber().isPresent()) { responseMessage.setThreadE164(message.getPerson().get().getNumber().get()); } - responseMessage.setThreadUuid(message.getPerson().get().getUuid().toString()); + responseMessage.setThreadUuid(message.getPerson().get().getAci().toString()); } switch (message.getType()) { @@ -1268,7 +1267,7 @@ public class SignalServiceMessageSender { SyncMessage.OutgoingPayment.Builder paymentMessage = SyncMessage.OutgoingPayment.newBuilder(); if (message.getRecipient().isPresent()) { - paymentMessage.setRecipientUuid(message.getRecipient().get().toString()); + paymentMessage.setRecipientUuid(message.getRecipient().get().getAci().toString()); } if (message.getNote().isPresent()) { @@ -1320,7 +1319,7 @@ public class SignalServiceMessageSender { verifiedMessageBuilder.setNullMessage(ByteString.copyFrom(nullMessage)); verifiedMessageBuilder.setIdentityKey(ByteString.copyFrom(verifiedMessage.getIdentityKey().serialize())); - verifiedMessageBuilder.setDestinationUuid(verifiedMessage.getDestination().getUuid().toString()); + verifiedMessageBuilder.setDestinationUuid(verifiedMessage.getDestination().getAci().toString()); if (verifiedMessage.getDestination().getNumber().isPresent()) { verifiedMessageBuilder.setDestinationE164(verifiedMessage.getDestination().getNumber().get()); @@ -1683,12 +1682,12 @@ public class SignalServiceMessageSender { Preconditions.checkArgument(recipients.size() == unidentifiedAccess.size(), "[" + timestamp + "] Unidentified access mismatch!"); - Map accessByUuid = new HashMap<>(); + Map accessByAci = new HashMap<>(); Iterator addressIterator = recipients.iterator(); Iterator accessIterator = unidentifiedAccess.iterator(); while (addressIterator.hasNext()) { - accessByUuid.put(addressIterator.next().getUuid(), accessIterator.next()); + accessByAci.put(addressIterator.next().getAci(), accessIterator.next()); } for (int i = 0; i < RETRY_COUNT; i++) { @@ -1696,7 +1695,7 @@ public class SignalServiceMessageSender { Set sharedWith = store.getSenderKeySharedWith(distributionId); List needsSenderKey = targetInfo.destinations.stream() .filter(a -> !sharedWith.contains(a)) - .map(a -> UuidUtil.parseOrThrow(a.getName())) + .map(a -> ACI.parseOrThrow(a.getName())) .distinct() .map(SignalServiceAddress::new) .collect(Collectors.toList()); @@ -1705,7 +1704,7 @@ public class SignalServiceMessageSender { SenderKeyDistributionMessage message = getOrCreateNewGroupSession(distributionId); List> access = needsSenderKey.stream() .map(r -> { - UnidentifiedAccess targetAccess = accessByUuid.get(r.getUuid()); + UnidentifiedAccess targetAccess = accessByAci.get(r.getAci()); return Optional.of(new UnidentifiedAccessPair(targetAccess, targetAccess)); }) .collect(Collectors.toList()); @@ -1717,7 +1716,7 @@ public class SignalServiceMessageSender { .map(SendMessageResult::getAddress) .collect(Collectors.toList()); - Set successUuids = successes.stream().map(a -> a.getUuid().toString()).collect(Collectors.toSet()); + Set successUuids = successes.stream().map(a -> a.getAci().toString()).collect(Collectors.toSet()); Set successAddresses = targetInfo.destinations.stream().filter(a -> successUuids.contains(a.getName())).collect(Collectors.toSet()); store.markSenderKeySharedWith(distributionId, successAddresses); @@ -1785,13 +1784,13 @@ public class SignalServiceMessageSender { } catch (GroupMismatchedDevicesException e) { Log.w(TAG, "[sendGroupMessage][" + timestamp + "] Handling mismatched devices.", e); for (GroupMismatchedDevices mismatched : e.getMismatchedDevices()) { - SignalServiceAddress address = new SignalServiceAddress(UuidUtil.parseOrThrow(mismatched.getUuid()), Optional.absent()); + SignalServiceAddress address = new SignalServiceAddress(ACI.parseOrThrow(mismatched.getUuid()), Optional.absent()); handleMismatchedDevices(socket, address, mismatched.getDevices()); } } catch (GroupStaleDevicesException e) { Log.w(TAG, "[sendGroupMessage][" + timestamp + "] Handling stale devices.", e); for (GroupStaleDevices stale : e.getStaleDevices()) { - SignalServiceAddress address = new SignalServiceAddress(UuidUtil.parseOrThrow(stale.getUuid()), Optional.absent()); + SignalServiceAddress address = new SignalServiceAddress(ACI.parseOrThrow(stale.getUuid()), Optional.absent()); handleStaleDevices(address, stale.getDevices()); } } @@ -1840,16 +1839,16 @@ public class SignalServiceMessageSender { } private List transformGroupResponseToMessageResults(Map> recipients, SendGroupMessageResponse response, Content content) { - Set unregistered = response.getUnsentTargets(); + Set unregistered = response.getUnsentTargets(); List failures = unregistered.stream() - .map(uuid -> new SignalServiceAddress(uuid)) + .map(SignalServiceAddress::new) .map(SendMessageResult::unregisteredFailure) .collect(Collectors.toList()); List success = recipients.keySet() .stream() - .filter(r -> !unregistered.contains(r.getUuid())) + .filter(r -> !unregistered.contains(r.getAci())) .map(a -> SendMessageResult.success(a, recipients.get(a), true, store.isMultiDevice(), -1, Optional.of(content))) .collect(Collectors.toList()); @@ -2049,7 +2048,7 @@ public class SignalServiceMessageSender { List addresses = new ArrayList<>(devices.size()); for (int staleDeviceId : devices) { - addresses.add(new SignalProtocolAddress(recipient.getUuid().toString(), staleDeviceId)); + addresses.add(new SignalProtocolAddress(recipient.getAci().toString(), staleDeviceId)); if (recipient.getNumber().isPresent()) { addresses.add(new SignalProtocolAddress(recipient.getNumber().get(), staleDeviceId)); diff --git a/libsignal/service/src/main/java/org/whispersystems/signalservice/api/crypto/SignalServiceCipher.java b/libsignal/service/src/main/java/org/whispersystems/signalservice/api/crypto/SignalServiceCipher.java index 0ffa10c6ed..f98dcd880f 100644 --- a/libsignal/service/src/main/java/org/whispersystems/signalservice/api/crypto/SignalServiceCipher.java +++ b/libsignal/service/src/main/java/org/whispersystems/signalservice/api/crypto/SignalServiceCipher.java @@ -46,6 +46,7 @@ import org.whispersystems.signalservice.api.SignalSessionLock; import org.whispersystems.signalservice.api.messages.SignalServiceContent; import org.whispersystems.signalservice.api.messages.SignalServiceEnvelope; import org.whispersystems.signalservice.api.messages.SignalServiceMetadata; +import org.whispersystems.signalservice.api.push.ACI; import org.whispersystems.signalservice.api.push.DistributionId; import org.whispersystems.signalservice.api.push.SignalServiceAddress; import org.whispersystems.signalservice.api.util.UuidUtil; @@ -94,7 +95,7 @@ public class SignalServiceCipher { PushTransportDetails transport = new PushTransportDetails(); SignalProtocolAddress localProtocolAddress = new SignalProtocolAddress(localAddress.getIdentifier(), SignalServiceAddress.DEFAULT_DEVICE_ID); SignalGroupCipher groupCipher = new SignalGroupCipher(sessionLock, new GroupCipher(signalProtocolStore, localProtocolAddress)); - SignalSealedSessionCipher sessionCipher = new SignalSealedSessionCipher(sessionLock, new SealedSessionCipher(signalProtocolStore, localAddress.getUuid(), localAddress.getNumber().orNull(), 1)); + SignalSealedSessionCipher sessionCipher = new SignalSealedSessionCipher(sessionLock, new SealedSessionCipher(signalProtocolStore, localAddress.getAci().uuid(), localAddress.getNumber().orNull(), 1)); CiphertextMessage message = groupCipher.encrypt(distributionId.asUuid(), transport.getPaddedMessageBody(unpaddedMessage)); UnidentifiedSenderMessageContent messageContent = new UnidentifiedSenderMessageContent(message, senderCertificate, @@ -111,7 +112,7 @@ public class SignalServiceCipher { { if (unidentifiedAccess.isPresent()) { SignalSessionCipher sessionCipher = new SignalSessionCipher(sessionLock, new SessionCipher(signalProtocolStore, destination)); - SignalSealedSessionCipher sealedSessionCipher = new SignalSealedSessionCipher(sessionLock, new SealedSessionCipher(signalProtocolStore, localAddress.getUuid(), localAddress.getNumber().orNull(), 1)); + SignalSealedSessionCipher sealedSessionCipher = new SignalSealedSessionCipher(sessionLock, new SealedSessionCipher(signalProtocolStore, localAddress.getAci().uuid(), localAddress.getNumber().orNull(), 1)); return content.processSealedSender(sessionCipher, sealedSessionCipher, destination, unidentifiedAccess.get().getUnidentifiedCertificate()); } else { @@ -197,9 +198,9 @@ public class SignalServiceCipher { paddedMessage = sessionCipher.decrypt(new SignalMessage(ciphertext)); metadata = new SignalServiceMetadata(envelope.getSourceAddress(), envelope.getSourceDevice(), envelope.getTimestamp(), envelope.getServerReceivedTimestamp(), envelope.getServerDeliveredTimestamp(), false, envelope.getServerGuid(), Optional.absent()); } else if (envelope.isUnidentifiedSender()) { - SignalSealedSessionCipher sealedSessionCipher = new SignalSealedSessionCipher(sessionLock, new SealedSessionCipher(signalProtocolStore, localAddress.getUuid(), localAddress.getNumber().orNull(), SignalServiceAddress.DEFAULT_DEVICE_ID)); + SignalSealedSessionCipher sealedSessionCipher = new SignalSealedSessionCipher(sessionLock, new SealedSessionCipher(signalProtocolStore, localAddress.getAci().uuid(), localAddress.getNumber().orNull(), SignalServiceAddress.DEFAULT_DEVICE_ID)); DecryptionResult result = sealedSessionCipher.decrypt(certificateValidator, ciphertext, envelope.getServerReceivedTimestamp()); - SignalServiceAddress resultAddress = new SignalServiceAddress(UuidUtil.parseOrThrow(result.getSenderUuid()), result.getSenderE164()); + SignalServiceAddress resultAddress = new SignalServiceAddress(ACI.parseOrThrow(result.getSenderUuid()), result.getSenderE164()); Optional groupId = result.getGroupId(); paddedMessage = result.getPaddedMessage(); diff --git a/libsignal/service/src/main/java/org/whispersystems/signalservice/api/groupsv2/GroupsV2Api.java b/libsignal/service/src/main/java/org/whispersystems/signalservice/api/groupsv2/GroupsV2Api.java index 5d75a50e47..8aae3d7653 100644 --- a/libsignal/service/src/main/java/org/whispersystems/signalservice/api/groupsv2/GroupsV2Api.java +++ b/libsignal/service/src/main/java/org/whispersystems/signalservice/api/groupsv2/GroupsV2Api.java @@ -21,6 +21,7 @@ import org.signal.zkgroup.auth.ClientZkAuthOperations; import org.signal.zkgroup.groups.ClientZkGroupCipher; import org.signal.zkgroup.groups.GroupSecretParams; import org.whispersystems.libsignal.util.guava.Optional; +import org.whispersystems.signalservice.api.push.ACI; import org.whispersystems.signalservice.internal.push.PushServiceSocket; import org.whispersystems.signalservice.internal.push.exceptions.ForbiddenException; @@ -54,14 +55,14 @@ public final class GroupsV2Api { /** * Create an auth token from a credential response. */ - public GroupsV2AuthorizationString getGroupsV2AuthorizationString(UUID self, + public GroupsV2AuthorizationString getGroupsV2AuthorizationString(ACI self, int today, GroupSecretParams groupSecretParams, AuthCredentialResponse authCredentialResponse) throws VerificationFailedException { ClientZkAuthOperations authOperations = groupsOperations.getAuthOperations(); - AuthCredential authCredential = authOperations.receiveAuthCredential(self, today, authCredentialResponse); + AuthCredential authCredential = authOperations.receiveAuthCredential(self.uuid(), today, authCredentialResponse); AuthCredentialPresentation authCredentialPresentation = authOperations.createAuthCredentialPresentation(new SecureRandom(), groupSecretParams, authCredential); return new GroupsV2AuthorizationString(groupSecretParams, authCredentialPresentation); diff --git a/libsignal/service/src/main/java/org/whispersystems/signalservice/api/messages/SignalServiceContent.java b/libsignal/service/src/main/java/org/whispersystems/signalservice/api/messages/SignalServiceContent.java index 37511b2793..4bb633b1b4 100644 --- a/libsignal/service/src/main/java/org/whispersystems/signalservice/api/messages/SignalServiceContent.java +++ b/libsignal/service/src/main/java/org/whispersystems/signalservice/api/messages/SignalServiceContent.java @@ -43,6 +43,7 @@ import org.whispersystems.signalservice.api.messages.multidevice.ViewOnceOpenMes import org.whispersystems.signalservice.api.messages.multidevice.ViewedMessage; import org.whispersystems.signalservice.api.messages.shared.SharedContact; import org.whispersystems.signalservice.api.payments.Money; +import org.whispersystems.signalservice.api.push.ACI; import org.whispersystems.signalservice.api.push.SignalServiceAddress; import org.whispersystems.signalservice.api.util.UuidUtil; import org.whispersystems.signalservice.internal.push.SignalServiceProtos; @@ -588,7 +589,7 @@ public final class SignalServiceContent { SignalServiceProtos.SyncMessage.Sent sentContent = content.getSent(); SignalServiceDataMessage dataMessage = createSignalServiceMessage(metadata, sentContent.getMessage()); Optional address = SignalServiceAddress.isValidAddress(sentContent.getDestinationUuid(), sentContent.getDestinationE164()) - ? Optional.of(new SignalServiceAddress(UuidUtil.parseOrThrow(sentContent.getDestinationUuid()), sentContent.getDestinationE164())) + ? Optional.of(new SignalServiceAddress(ACI.parseOrThrow(sentContent.getDestinationUuid()), sentContent.getDestinationE164())) : Optional.absent(); if (!address.isPresent() && !dataMessage.getGroupContext().isPresent()) { @@ -597,7 +598,7 @@ public final class SignalServiceContent { for (SignalServiceProtos.SyncMessage.Sent.UnidentifiedDeliveryStatus status : sentContent.getUnidentifiedStatusList()) { if (SignalServiceAddress.isValidAddress(status.getDestinationUuid(), status.getDestinationE164())) { - SignalServiceAddress recipient = new SignalServiceAddress(UuidUtil.parseOrThrow(status.getDestinationUuid()), status.getDestinationE164()); + SignalServiceAddress recipient = new SignalServiceAddress(ACI.parseOrThrow(status.getDestinationUuid()), status.getDestinationE164()); unidentifiedStatuses.put(recipient, status.getUnidentified()); } else { Log.w(TAG, "Encountered an invalid UnidentifiedDeliveryStatus in a SentTranscript! Ignoring."); @@ -621,7 +622,7 @@ public final class SignalServiceContent { for (SignalServiceProtos.SyncMessage.Read read : content.getReadList()) { if (SignalServiceAddress.isValidAddress(read.getSenderUuid(), read.getSenderE164())) { - SignalServiceAddress address = new SignalServiceAddress(UuidUtil.parseOrThrow(read.getSenderUuid()), read.getSenderE164()); + SignalServiceAddress address = new SignalServiceAddress(ACI.parseOrThrow(read.getSenderUuid()), read.getSenderE164()); readMessages.add(new ReadMessage(address, read.getTimestamp())); } else { Log.w(TAG, "Encountered an invalid ReadMessage! Ignoring."); @@ -636,7 +637,7 @@ public final class SignalServiceContent { for (SignalServiceProtos.SyncMessage.Viewed viewed : content.getViewedList()) { if (SignalServiceAddress.isValidAddress(viewed.getSenderUuid(), viewed.getSenderE164())) { - SignalServiceAddress address = new SignalServiceAddress(UuidUtil.parseOrThrow(viewed.getSenderUuid()), viewed.getSenderE164()); + SignalServiceAddress address = new SignalServiceAddress(ACI.parseOrThrow(viewed.getSenderUuid()), viewed.getSenderE164()); viewedMessages.add(new ViewedMessage(address, viewed.getTimestamp())); } else { Log.w(TAG, "Encountered an invalid ReadMessage! Ignoring."); @@ -648,8 +649,8 @@ public final class SignalServiceContent { if (content.hasViewOnceOpen()) { if (SignalServiceAddress.isValidAddress(content.getViewOnceOpen().getSenderUuid(), content.getViewOnceOpen().getSenderE164())) { - SignalServiceAddress address = new SignalServiceAddress(UuidUtil.parseOrThrow(content.getViewOnceOpen().getSenderUuid()), content.getViewOnceOpen().getSenderE164()); - ViewOnceOpenMessage timerRead = new ViewOnceOpenMessage(address, content.getViewOnceOpen().getTimestamp()); + SignalServiceAddress address = new SignalServiceAddress(ACI.parseOrThrow(content.getViewOnceOpen().getSenderUuid()), content.getViewOnceOpen().getSenderE164()); + ViewOnceOpenMessage timerRead = new ViewOnceOpenMessage(address, content.getViewOnceOpen().getTimestamp()); return SignalServiceSyncMessage.forViewOnceOpen(timerRead); } else { throw new InvalidMessageStructureException("ViewOnceOpen message has no sender!"); @@ -660,7 +661,7 @@ public final class SignalServiceContent { if (SignalServiceAddress.isValidAddress(content.getVerified().getDestinationUuid(), content.getVerified().getDestinationE164())) { try { SignalServiceProtos.Verified verified = content.getVerified(); - SignalServiceAddress destination = new SignalServiceAddress(UuidUtil.parseOrThrow(verified.getDestinationUuid()), verified.getDestinationE164()); + SignalServiceAddress destination = new SignalServiceAddress(ACI.parseOrThrow(verified.getDestinationUuid()), verified.getDestinationE164()); IdentityKey identityKey = new IdentityKey(verified.getIdentityKey().toByteArray(), 0); VerifiedMessage.VerifiedState verifiedState; @@ -791,7 +792,7 @@ public final class SignalServiceContent { Money.MobileCoin amount = Money.picoMobileCoin(mobileCoin.getAmountPicoMob()); Money.MobileCoin fee = Money.picoMobileCoin(mobileCoin.getFeePicoMob()); ByteString address = mobileCoin.getRecipientAddress(); - Optional recipient = Optional.fromNullable(UuidUtil.parseOrNull(outgoingPayment.getRecipientUuid())); + Optional recipient = SignalServiceAddress.fromRaw(outgoingPayment.getRecipientUuid(), null); return SignalServiceSyncMessage.forOutgoingPayment(new OutgoingPaymentMessage(recipient, amount, @@ -898,7 +899,7 @@ public final class SignalServiceContent { } if (SignalServiceAddress.isValidAddress(content.getQuote().getAuthorUuid(), content.getQuote().getAuthorE164())) { - SignalServiceAddress address = new SignalServiceAddress(UuidUtil.parseOrThrow(content.getQuote().getAuthorUuid()), content.getQuote().getAuthorE164()); + SignalServiceAddress address = new SignalServiceAddress(ACI.parseOrThrow(content.getQuote().getAuthorUuid()), content.getQuote().getAuthorE164()); return new SignalServiceDataMessage.Quote(content.getQuote().getId(), address, @@ -945,7 +946,7 @@ public final class SignalServiceContent { for (SignalServiceProtos.DataMessage.BodyRange bodyRange : bodyRanges) { if (bodyRange.hasMentionUuid()) { try { - mentions.add(new SignalServiceDataMessage.Mention(UuidUtil.parseOrThrow(bodyRange.getMentionUuid()), bodyRange.getStart(), bodyRange.getLength())); + mentions.add(new SignalServiceDataMessage.Mention(ACI.parseOrThrow(bodyRange.getMentionUuid()), bodyRange.getStart(), bodyRange.getLength())); } catch (IllegalArgumentException e) { throw new InvalidMessageStructureException("Invalid body range!"); } @@ -988,7 +989,7 @@ public final class SignalServiceContent { } SignalServiceProtos.DataMessage.Reaction reaction = content.getReaction(); - UUID uuid = UuidUtil.parseOrNull(reaction.getTargetAuthorUuid()); + ACI uuid = ACI.parseOrNull(reaction.getTargetAuthorUuid()); if (uuid == null) { Log.w(TAG, "Cannot parse author UUID on reaction"); @@ -996,9 +997,9 @@ public final class SignalServiceContent { } return new SignalServiceDataMessage.Reaction(reaction.getEmoji(), - reaction.getRemove(), - new SignalServiceAddress(uuid), - reaction.getTargetSentTimestamp()); + reaction.getRemove(), + new SignalServiceAddress(uuid), + reaction.getTargetSentTimestamp()); } private static SignalServiceDataMessage.RemoteDelete createRemoteDelete(SignalServiceProtos.DataMessage content) { diff --git a/libsignal/service/src/main/java/org/whispersystems/signalservice/api/messages/SignalServiceDataMessage.java b/libsignal/service/src/main/java/org/whispersystems/signalservice/api/messages/SignalServiceDataMessage.java index 812d0a7530..5c32229147 100644 --- a/libsignal/service/src/main/java/org/whispersystems/signalservice/api/messages/SignalServiceDataMessage.java +++ b/libsignal/service/src/main/java/org/whispersystems/signalservice/api/messages/SignalServiceDataMessage.java @@ -10,6 +10,7 @@ import org.signal.zkgroup.groups.GroupSecretParams; import org.whispersystems.libsignal.InvalidMessageException; import org.whispersystems.libsignal.util.guava.Optional; import org.whispersystems.signalservice.api.messages.shared.SharedContact; +import org.whispersystems.signalservice.api.push.ACI; import org.whispersystems.signalservice.api.push.SignalServiceAddress; import org.whispersystems.signalservice.api.util.OptionalUtil; @@ -585,18 +586,18 @@ public class SignalServiceDataMessage { } public static class Mention { - private final UUID uuid; - private final int start; - private final int length; + private final ACI aci; + private final int start; + private final int length; - public Mention(UUID uuid, int start, int length) { - this.uuid = uuid; + public Mention(ACI aci, int start, int length) { + this.aci = aci; this.start = start; this.length = length; } - public UUID getUuid() { - return uuid; + public ACI getAci() { + return aci; } public int getStart() { diff --git a/libsignal/service/src/main/java/org/whispersystems/signalservice/api/messages/SignalServiceEnvelope.java b/libsignal/service/src/main/java/org/whispersystems/signalservice/api/messages/SignalServiceEnvelope.java index c68b1101c0..f1670761bc 100644 --- a/libsignal/service/src/main/java/org/whispersystems/signalservice/api/messages/SignalServiceEnvelope.java +++ b/libsignal/service/src/main/java/org/whispersystems/signalservice/api/messages/SignalServiceEnvelope.java @@ -10,6 +10,7 @@ import com.google.protobuf.ByteString; import com.google.protobuf.InvalidProtocolBufferException; import org.whispersystems.libsignal.util.guava.Optional; +import org.whispersystems.signalservice.api.push.ACI; import org.whispersystems.signalservice.api.push.SignalServiceAddress; import org.whispersystems.signalservice.api.util.UuidUtil; import org.whispersystems.signalservice.internal.push.SignalServiceProtos.Envelope; @@ -70,7 +71,7 @@ public class SignalServiceEnvelope { .setServerTimestamp(serverReceivedTimestamp); if (sender.isPresent()) { - builder.setSourceUuid(sender.get().getUuid().toString()); + builder.setSourceUuid(sender.get().getAci().toString()); if (sender.get().getNumber().isPresent()) { builder.setSourceE164(sender.get().getNumber().get()); @@ -160,7 +161,7 @@ public class SignalServiceEnvelope { * @return The envelope's sender as a SignalServiceAddress. */ public SignalServiceAddress getSourceAddress() { - return new SignalServiceAddress(UuidUtil.parseOrNull(envelope.getSourceUuid()), envelope.getSourceE164()); + return new SignalServiceAddress(ACI.parseOrNull(envelope.getSourceUuid()), envelope.getSourceE164()); } /** diff --git a/libsignal/service/src/main/java/org/whispersystems/signalservice/api/messages/multidevice/DeviceContactsInputStream.java b/libsignal/service/src/main/java/org/whispersystems/signalservice/api/messages/multidevice/DeviceContactsInputStream.java index 55b95db3ba..62e4e314ce 100644 --- a/libsignal/service/src/main/java/org/whispersystems/signalservice/api/messages/multidevice/DeviceContactsInputStream.java +++ b/libsignal/service/src/main/java/org/whispersystems/signalservice/api/messages/multidevice/DeviceContactsInputStream.java @@ -14,6 +14,7 @@ import org.whispersystems.libsignal.InvalidMessageException; import org.whispersystems.libsignal.logging.Log; import org.whispersystems.libsignal.util.guava.Optional; import org.whispersystems.signalservice.api.messages.SignalServiceAttachmentStream; +import org.whispersystems.signalservice.api.push.ACI; import org.whispersystems.signalservice.api.push.SignalServiceAddress; import org.whispersystems.signalservice.api.util.UuidUtil; import org.whispersystems.signalservice.internal.push.SignalServiceProtos; @@ -41,7 +42,7 @@ public class DeviceContactsInputStream extends ChunkedInputStream { throw new IOException("Missing contact address!"); } - SignalServiceAddress address = new SignalServiceAddress(UuidUtil.parseOrThrow(details.getUuid()), details.getNumber()); + SignalServiceAddress address = new SignalServiceAddress(ACI.parseOrThrow(details.getUuid()), details.getNumber()); Optional name = Optional.fromNullable(details.getName()); Optional avatar = Optional.absent(); Optional color = details.hasColor() ? Optional.of(details.getColor()) : Optional.absent(); @@ -66,7 +67,7 @@ public class DeviceContactsInputStream extends ChunkedInputStream { throw new InvalidMessageException("Missing Verified address!"); } IdentityKey identityKey = new IdentityKey(details.getVerified().getIdentityKey().toByteArray(), 0); - SignalServiceAddress destination = new SignalServiceAddress(UuidUtil.parseOrThrow(details.getVerified().getDestinationUuid()), + SignalServiceAddress destination = new SignalServiceAddress(ACI.parseOrThrow(details.getVerified().getDestinationUuid()), details.getVerified().getDestinationE164()); VerifiedMessage.VerifiedState state; 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 81f0039e93..27820f1adf 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 @@ -37,7 +37,7 @@ public class DeviceContactsOutputStream extends ChunkedOutputStream { private void writeContactDetails(DeviceContact contact) throws IOException { SignalServiceProtos.ContactDetails.Builder contactDetails = SignalServiceProtos.ContactDetails.newBuilder(); - contactDetails.setUuid(contact.getAddress().getUuid().toString()); + contactDetails.setUuid(contact.getAddress().getAci().toString()); if (contact.getAddress().getNumber().isPresent()) { contactDetails.setNumber(contact.getAddress().getNumber().get()); @@ -69,7 +69,7 @@ public class DeviceContactsOutputStream extends ChunkedOutputStream { SignalServiceProtos.Verified.Builder verifiedBuilder = SignalServiceProtos.Verified.newBuilder() .setIdentityKey(ByteString.copyFrom(contact.getVerified().get().getIdentityKey().serialize())) - .setDestinationUuid(contact.getVerified().get().getDestination().getUuid().toString()) + .setDestinationUuid(contact.getVerified().get().getDestination().getAci().toString()) .setState(state); if (contact.getVerified().get().getDestination().getNumber().isPresent()) { diff --git a/libsignal/service/src/main/java/org/whispersystems/signalservice/api/messages/multidevice/OutgoingPaymentMessage.java b/libsignal/service/src/main/java/org/whispersystems/signalservice/api/messages/multidevice/OutgoingPaymentMessage.java index 7b3110dd8b..882a76398b 100644 --- a/libsignal/service/src/main/java/org/whispersystems/signalservice/api/messages/multidevice/OutgoingPaymentMessage.java +++ b/libsignal/service/src/main/java/org/whispersystems/signalservice/api/messages/multidevice/OutgoingPaymentMessage.java @@ -4,24 +4,25 @@ import com.google.protobuf.ByteString; import org.whispersystems.libsignal.util.guava.Optional; import org.whispersystems.signalservice.api.payments.Money; +import org.whispersystems.signalservice.api.push.SignalServiceAddress; import java.util.List; import java.util.UUID; public final class OutgoingPaymentMessage { - private final Optional recipient; - private final Money.MobileCoin amount; - private final Money.MobileCoin fee; - private final ByteString receipt; - private final long blockIndex; - private final long blockTimestamp; - private final Optional address; - private final Optional note; - private final List publicKeys; - private final List keyImages; + private final Optional recipient; + private final Money.MobileCoin amount; + private final Money.MobileCoin fee; + private final ByteString receipt; + private final long blockIndex; + private final long blockTimestamp; + private final Optional address; + private final Optional note; + private final List publicKeys; + private final List keyImages; - public OutgoingPaymentMessage(Optional recipient, + public OutgoingPaymentMessage(Optional recipient, Money.MobileCoin amount, Money.MobileCoin fee, ByteString receipt, @@ -44,7 +45,7 @@ public final class OutgoingPaymentMessage { this.keyImages = keyImages; } - public Optional getRecipient() { + public Optional getRecipient() { return recipient; } diff --git a/libsignal/service/src/main/java/org/whispersystems/signalservice/api/messages/multidevice/SentTranscriptMessage.java b/libsignal/service/src/main/java/org/whispersystems/signalservice/api/messages/multidevice/SentTranscriptMessage.java index 6fa153de84..b7c8b83efe 100644 --- a/libsignal/service/src/main/java/org/whispersystems/signalservice/api/messages/multidevice/SentTranscriptMessage.java +++ b/libsignal/service/src/main/java/org/whispersystems/signalservice/api/messages/multidevice/SentTranscriptMessage.java @@ -8,15 +8,12 @@ package org.whispersystems.signalservice.api.messages.multidevice; import org.whispersystems.libsignal.util.guava.Optional; import org.whispersystems.signalservice.api.messages.SignalServiceDataMessage; +import org.whispersystems.signalservice.api.push.ACI; import org.whispersystems.signalservice.api.push.SignalServiceAddress; -import java.util.ArrayList; -import java.util.Collections; import java.util.HashMap; -import java.util.List; import java.util.Map; import java.util.Set; -import java.util.UUID; public class SentTranscriptMessage { @@ -24,7 +21,7 @@ public class SentTranscriptMessage { private final long timestamp; private final long expirationStartTimestamp; private final SignalServiceDataMessage message; - private final Map unidentifiedStatusByUuid; + private final Map unidentifiedStatusByAci; private final Map unidentifiedStatusByE164; private final Set recipients; private final boolean isRecipientUpdate; @@ -37,13 +34,13 @@ public class SentTranscriptMessage { this.timestamp = timestamp; this.message = message; this.expirationStartTimestamp = expirationStartTimestamp; - this.unidentifiedStatusByUuid = new HashMap<>(); + this.unidentifiedStatusByAci = new HashMap<>(); this.unidentifiedStatusByE164 = new HashMap<>(); this.recipients = unidentifiedStatus.keySet(); this.isRecipientUpdate = isRecipientUpdate; for (Map.Entry entry : unidentifiedStatus.entrySet()) { - unidentifiedStatusByUuid.put(entry.getKey().getUuid().toString(), entry.getValue()); + unidentifiedStatusByAci.put(entry.getKey().getAci().toString(), entry.getValue()); if (entry.getKey().getNumber().isPresent()) { unidentifiedStatusByE164.put(entry.getKey().getNumber().get(), entry.getValue()); @@ -67,13 +64,13 @@ public class SentTranscriptMessage { return message; } - public boolean isUnidentified(UUID uuid) { - return isUnidentified(uuid.toString()); + public boolean isUnidentified(ACI aci) { + return isUnidentified(aci.toString()); } public boolean isUnidentified(String destination) { - if (unidentifiedStatusByUuid.containsKey(destination)) { - return unidentifiedStatusByUuid.get(destination); + if (unidentifiedStatusByAci.containsKey(destination)) { + return unidentifiedStatusByAci.get(destination); } else if (unidentifiedStatusByE164.containsKey(destination)) { return unidentifiedStatusByE164.get(destination); } else { diff --git a/libsignal/service/src/main/java/org/whispersystems/signalservice/api/profiles/SignalServiceProfile.java b/libsignal/service/src/main/java/org/whispersystems/signalservice/api/profiles/SignalServiceProfile.java index 1e8de5bf2a..7646acb1c7 100644 --- a/libsignal/service/src/main/java/org/whispersystems/signalservice/api/profiles/SignalServiceProfile.java +++ b/libsignal/service/src/main/java/org/whispersystems/signalservice/api/profiles/SignalServiceProfile.java @@ -11,6 +11,7 @@ import com.fasterxml.jackson.databind.annotation.JsonSerialize; import org.signal.zkgroup.InvalidInputException; import org.signal.zkgroup.profiles.ProfileKeyCredentialResponse; import org.whispersystems.libsignal.logging.Log; +import org.whispersystems.signalservice.api.push.ACI; import org.whispersystems.signalservice.internal.util.JsonUtil; import java.math.BigDecimal; @@ -54,9 +55,9 @@ public class SignalServiceProfile { private Capabilities capabilities; @JsonProperty - @JsonSerialize(using = JsonUtil.UuidSerializer.class) - @JsonDeserialize(using = JsonUtil.UuidDeserializer.class) - private UUID uuid; + @JsonSerialize(using = JsonUtil.AciSerializer.class) + @JsonDeserialize(using = JsonUtil.AciDeserializer.class) + private ACI uuid; @JsonProperty private byte[] credential; @@ -109,7 +110,7 @@ public class SignalServiceProfile { return badges; } - public UUID getUuid() { + public ACI getAci() { return uuid; } diff --git a/libsignal/service/src/main/java/org/whispersystems/signalservice/api/push/ACI.java b/libsignal/service/src/main/java/org/whispersystems/signalservice/api/push/ACI.java new file mode 100644 index 0000000000..d7db3bd715 --- /dev/null +++ b/libsignal/service/src/main/java/org/whispersystems/signalservice/api/push/ACI.java @@ -0,0 +1,112 @@ +package org.whispersystems.signalservice.api.push; + +import com.google.protobuf.ByteString; + +import org.whispersystems.libsignal.util.guava.Optional; +import org.whispersystems.signalservice.api.util.UuidUtil; + +import java.util.Collection; +import java.util.List; +import java.util.UUID; +import java.util.stream.Collectors; + +import io.reactivex.rxjava3.annotations.NonNull; + +/** + * An ACI is an "Account Identity". They're just UUIDs, but given multiple different things could be UUIDs, this wrapper exists to give us type safety around + * this *specific type* of UUID. + */ +public final class ACI { + + public static final ACI UNKNOWN = ACI.from(UuidUtil.UNKNOWN_UUID); + + private final UUID uuid; + + public static ACI from(UUID uuid) { + return new ACI(uuid); + } + + public static Optional parse(String raw) { + return UuidUtil.parse(raw).transform(ACI::from); + } + + public static ACI parseOrThrow(String raw) { + return from(UUID.fromString(raw)); + } + + public static ACI parseOrThrow(byte[] raw) { + return from(UuidUtil.parseOrThrow(raw)); + } + + public static ACI parseOrNull(String raw) { + UUID uuid = UuidUtil.parseOrNull(raw); + return uuid != null ? from(uuid) : null; + } + + public static ACI parseOrNull(byte[] raw) { + UUID uuid = UuidUtil.parseOrNull(raw); + return uuid != null ? from(uuid) : null; + } + + public static ACI parseOrUnknown(String raw) { + ACI aci = parseOrNull(raw); + return aci != null ? aci : UNKNOWN; + } + + public static ACI fromByteString(ByteString bytes) { + return parseOrThrow(bytes.toByteArray()); + } + + public static ACI fromByteStringOrNull(ByteString bytes) { + UUID uuid = UuidUtil.fromByteStringOrNull(bytes); + return uuid != null ? from(uuid) : null; + } + + public static ACI fromByteStringOrUnknown(ByteString bytes) { + ACI uuid = fromByteStringOrNull(bytes); + return uuid != null ? uuid : UNKNOWN; + } + + public static List filterKnown(@NonNull Collection acis) { + return acis.stream().filter(aci -> !aci.equals(UNKNOWN)).collect(Collectors.toList()); + } + + private ACI(UUID uuid) { + this.uuid = uuid; + } + + public UUID uuid() { + return uuid; + } + + public ByteString toByteString() { + return UuidUtil.toByteString(uuid); + } + + public byte[] toByteArray() { + return UuidUtil.toByteArray(uuid); + } + + public boolean isUnknown() { + return this.equals(UNKNOWN); + } + + @Override + public int hashCode() { + return uuid.hashCode(); + } + + @Override + public boolean equals(Object other) { + if (other instanceof ACI) { + return uuid.equals(((ACI) other).uuid); + } else { + return false; + } + } + + @Override + public String toString() { + return uuid.toString(); + } +} diff --git a/libsignal/service/src/main/java/org/whispersystems/signalservice/api/push/SignalServiceAddress.java b/libsignal/service/src/main/java/org/whispersystems/signalservice/api/push/SignalServiceAddress.java index 59344692bd..c7c42394f2 100644 --- a/libsignal/service/src/main/java/org/whispersystems/signalservice/api/push/SignalServiceAddress.java +++ b/libsignal/service/src/main/java/org/whispersystems/signalservice/api/push/SignalServiceAddress.java @@ -12,7 +12,6 @@ import org.whispersystems.signalservice.api.util.OptionalUtil; import org.whispersystems.signalservice.api.util.UuidUtil; import java.util.Objects; -import java.util.UUID; /** * A class representing a message destination or origin. @@ -21,50 +20,50 @@ public class SignalServiceAddress { public static final int DEFAULT_DEVICE_ID = 1; - private final UUID uuid; + private final ACI aci; private final Optional e164; /** * Construct a PushAddress. * - * @param uuid The UUID of the user, if available. + * @param aci The UUID of the user, if available. * @param e164 The phone number of the user, if available. */ - public SignalServiceAddress(UUID uuid, Optional e164) { - this.uuid = Preconditions.checkNotNull(uuid); - this.e164 = e164; + public SignalServiceAddress(ACI aci, Optional e164) { + this.aci = Preconditions.checkNotNull(aci); + this.e164 = e164; } - public SignalServiceAddress(UUID uuid) { - this.uuid = Preconditions.checkNotNull(uuid); + public SignalServiceAddress(ACI aci) { + this.aci = Preconditions.checkNotNull(aci); this.e164 = Optional.absent(); } /** * Convenience constructor that will consider a UUID/E164 string absent if it is null or empty. */ - public SignalServiceAddress(UUID uuid, String e164) { - this(uuid, OptionalUtil.absentIfEmpty(e164)); + public SignalServiceAddress(ACI aci, String e164) { + this(aci, OptionalUtil.absentIfEmpty(e164)); } public Optional getNumber() { return e164; } - public UUID getUuid() { - return uuid; + public ACI getAci() { + return aci; } - public boolean hasValidUuid() { - return !uuid.equals(UuidUtil.UNKNOWN_UUID); + public boolean hasValidAci() { + return !aci.uuid().equals(UuidUtil.UNKNOWN_UUID); } public String getIdentifier() { - return uuid.toString(); + return aci.toString(); } public boolean matches(SignalServiceAddress other) { - return this.uuid.equals(other.uuid); + return this.aci.equals(other.aci); } public static boolean isValidAddress(String rawUuid, String e164) { @@ -73,7 +72,7 @@ public class SignalServiceAddress { public static Optional fromRaw(String rawUuid, String e164) { if (isValidAddress(rawUuid, e164)) { - return Optional.of(new SignalServiceAddress(UuidUtil.parseOrThrow(rawUuid), e164)); + return Optional.of(new SignalServiceAddress(ACI.parseOrThrow(rawUuid), e164)); } else { return Optional.absent(); } @@ -83,10 +82,10 @@ public class SignalServiceAddress { if (this == o) return true; if (o == null || getClass() != o.getClass()) return false; final SignalServiceAddress that = (SignalServiceAddress) o; - return uuid.equals(that.uuid) && e164.equals(that.e164); + return aci.equals(that.aci) && e164.equals(that.e164); } @Override public int hashCode() { - return Objects.hash(uuid, e164); + return Objects.hash(aci, e164); } } diff --git a/libsignal/service/src/main/java/org/whispersystems/signalservice/api/services/CdshService.java b/libsignal/service/src/main/java/org/whispersystems/signalservice/api/services/CdshService.java index dcf16c7b46..dfeddd681d 100644 --- a/libsignal/service/src/main/java/org/whispersystems/signalservice/api/services/CdshService.java +++ b/libsignal/service/src/main/java/org/whispersystems/signalservice/api/services/CdshService.java @@ -4,6 +4,7 @@ import org.signal.libsignal.hsmenclave.HsmEnclaveClient; import org.whispersystems.libsignal.logging.Log; import org.whispersystems.libsignal.util.ByteUtil; import org.whispersystems.libsignal.util.Pair; +import org.whispersystems.signalservice.api.push.ACI; import org.whispersystems.signalservice.api.push.TrustStore; import org.whispersystems.signalservice.api.util.Tls12SocketFactory; import org.whispersystems.signalservice.internal.ServiceResponse; @@ -33,11 +34,7 @@ import javax.net.ssl.SSLSocketFactory; import javax.net.ssl.TrustManager; import javax.net.ssl.X509TrustManager; -import io.reactivex.rxjava3.annotations.NonNull; import io.reactivex.rxjava3.core.Single; -import io.reactivex.rxjava3.core.SingleEmitter; -import io.reactivex.rxjava3.core.SingleOnSubscribe; -import io.reactivex.rxjava3.subjects.PublishSubject; import okhttp3.ConnectionSpec; import okhttp3.OkHttpClient; import okhttp3.Request; @@ -84,7 +81,7 @@ public final class CdshService { } } - public Single>> getRegisteredUsers(Set e164Numbers) { + public Single>> getRegisteredUsers(Set e164Numbers) { return Single.create(emitter -> { AtomicReference stage = new AtomicReference<>(Stage.WAITING_TO_INITIALIZE); List addressBook = e164Numbers.stream().map(e -> e.substring(1)).collect(Collectors.toList()); @@ -108,7 +105,7 @@ public final class CdshService { byte[] response = enclave.establishedRecv(bytes.toByteArray()); try { - Map out = parseResponse(addressBook, response); + Map out = parseResponse(addressBook, response); emitter.onSuccess(ServiceResponse.forResult(out, 200, null)); } catch (IOException e) { emitter.onSuccess(ServiceResponse.forUnknownError(e)); @@ -150,15 +147,15 @@ public final class CdshService { } } - private static Map parseResponse(List addressBook, byte[] plaintextResponse) throws IOException { - Map results = new HashMap<>(); + private static Map parseResponse(List addressBook, byte[] plaintextResponse) throws IOException { + Map results = new HashMap<>(); try (DataInputStream uuidInputStream = new DataInputStream(new ByteArrayInputStream(plaintextResponse))) { for (String candidate : addressBook) { long candidateUuidHigh = uuidInputStream.readLong(); long candidateUuidLow = uuidInputStream.readLong(); if (candidateUuidHigh != 0 || candidateUuidLow != 0) { - results.put('+' + candidate, new UUID(candidateUuidHigh, candidateUuidLow)); + results.put('+' + candidate, ACI.from(new UUID(candidateUuidHigh, candidateUuidLow))); } } } diff --git a/libsignal/service/src/main/java/org/whispersystems/signalservice/api/services/ProfileService.java b/libsignal/service/src/main/java/org/whispersystems/signalservice/api/services/ProfileService.java index b7744e3415..b8384ba74a 100644 --- a/libsignal/service/src/main/java/org/whispersystems/signalservice/api/services/ProfileService.java +++ b/libsignal/service/src/main/java/org/whispersystems/signalservice/api/services/ProfileService.java @@ -15,6 +15,7 @@ import org.whispersystems.signalservice.api.SignalWebSocket; import org.whispersystems.signalservice.api.crypto.UnidentifiedAccess; import org.whispersystems.signalservice.api.profiles.ProfileAndCredential; import org.whispersystems.signalservice.api.profiles.SignalServiceProfile; +import org.whispersystems.signalservice.api.push.ACI; import org.whispersystems.signalservice.api.push.SignalServiceAddress; import org.whispersystems.signalservice.api.push.exceptions.MalformedResponseException; import org.whispersystems.signalservice.internal.ServiceResponse; @@ -60,8 +61,8 @@ public final class ProfileService { SignalServiceProfile.RequestType requestType, Locale locale) { - UUID uuid = address.getUuid(); - SecureRandom random = new SecureRandom(); + ACI aci = address.getAci(); + SecureRandom random = new SecureRandom(); ProfileKeyCredentialRequestContext requestContext = null; WebSocketProtos.WebSocketRequestMessage.Builder builder = WebSocketProtos.WebSocketRequestMessage.newBuilder() @@ -69,18 +70,18 @@ public final class ProfileService { .setVerb("GET"); if (profileKey.isPresent()) { - ProfileKeyVersion profileKeyIdentifier = profileKey.get().getProfileKeyVersion(uuid); + ProfileKeyVersion profileKeyIdentifier = profileKey.get().getProfileKeyVersion(aci.uuid()); String version = profileKeyIdentifier.serialize(); if (requestType == SignalServiceProfile.RequestType.PROFILE_AND_CREDENTIAL) { - requestContext = clientZkProfileOperations.createProfileKeyCredentialRequestContext(random, uuid, profileKey.get()); + requestContext = clientZkProfileOperations.createProfileKeyCredentialRequestContext(random, aci.uuid(), profileKey.get()); ProfileKeyCredentialRequest request = requestContext.getRequest(); String credentialRequest = Hex.toStringCondensed(request.serialize()); - builder.setPath(String.format("/v1/profile/%s/%s/%s", uuid, version, credentialRequest)); + builder.setPath(String.format("/v1/profile/%s/%s/%s", aci, version, credentialRequest)); } else { - builder.setPath(String.format("/v1/profile/%s/%s", uuid, version)); + builder.setPath(String.format("/v1/profile/%s/%s", aci, version)); } } else { builder.setPath(String.format("/v1/profile/%s", address.getIdentifier())); diff --git a/libsignal/service/src/main/java/org/whispersystems/signalservice/api/storage/SignalAccountRecord.java b/libsignal/service/src/main/java/org/whispersystems/signalservice/api/storage/SignalAccountRecord.java index 79ceebe0a0..9142c8319d 100644 --- a/libsignal/service/src/main/java/org/whispersystems/signalservice/api/storage/SignalAccountRecord.java +++ b/libsignal/service/src/main/java/org/whispersystems/signalservice/api/storage/SignalAccountRecord.java @@ -6,6 +6,7 @@ import com.google.protobuf.InvalidProtocolBufferException; import org.whispersystems.libsignal.logging.Log; import org.whispersystems.libsignal.util.guava.Optional; import org.whispersystems.signalservice.api.payments.PaymentsConstants; +import org.whispersystems.signalservice.api.push.ACI; import org.whispersystems.signalservice.api.push.SignalServiceAddress; import org.whispersystems.signalservice.api.util.OptionalUtil; import org.whispersystems.signalservice.api.util.ProtoUtil; @@ -289,7 +290,7 @@ public final class SignalAccountRecord implements SignalRecord { static PinnedConversation fromRemote(AccountRecord.PinnedConversation remote) { if (remote.hasContact()) { - return forContact(new SignalServiceAddress(UuidUtil.parseOrThrow(remote.getContact().getUuid()), remote.getContact().getE164())); + return forContact(new SignalServiceAddress(ACI.parseOrThrow(remote.getContact().getUuid()), remote.getContact().getE164())); } else if (!remote.getLegacyGroupId().isEmpty()) { return forGroupV1(remote.getLegacyGroupId().toByteArray()); } else if (!remote.getGroupMasterKey().isEmpty()) { @@ -319,7 +320,7 @@ public final class SignalAccountRecord implements SignalRecord { if (contact.isPresent()) { AccountRecord.PinnedConversation.Contact.Builder contactBuilder = AccountRecord.PinnedConversation.Contact.newBuilder(); - contactBuilder.setUuid(contact.get().getUuid().toString()); + contactBuilder.setUuid(contact.get().getAci().toString()); if (contact.get().getNumber().isPresent()) { contactBuilder.setE164(contact.get().getNumber().get()); diff --git a/libsignal/service/src/main/java/org/whispersystems/signalservice/api/storage/SignalContactRecord.java b/libsignal/service/src/main/java/org/whispersystems/signalservice/api/storage/SignalContactRecord.java index 4d693d9c50..63039f8e1a 100644 --- a/libsignal/service/src/main/java/org/whispersystems/signalservice/api/storage/SignalContactRecord.java +++ b/libsignal/service/src/main/java/org/whispersystems/signalservice/api/storage/SignalContactRecord.java @@ -5,6 +5,7 @@ import com.google.protobuf.InvalidProtocolBufferException; import org.whispersystems.libsignal.logging.Log; import org.whispersystems.libsignal.util.guava.Optional; +import org.whispersystems.signalservice.api.push.ACI; import org.whispersystems.signalservice.api.push.SignalServiceAddress; import org.whispersystems.signalservice.api.util.OptionalUtil; import org.whispersystems.signalservice.api.util.ProtoUtil; @@ -37,7 +38,7 @@ public final class SignalContactRecord implements SignalRecord { this.proto = proto; this.hasUnknownFields = ProtoUtil.hasUnknownFields(proto); - this.address = new SignalServiceAddress(UuidUtil.parseOrUnknown(proto.getServiceUuid()), proto.getServiceE164()); + this.address = new SignalServiceAddress(ACI.parseOrUnknown(proto.getServiceUuid()), proto.getServiceE164()); this.givenName = OptionalUtil.absentIfEmpty(proto.getGivenName()); this.familyName = OptionalUtil.absentIfEmpty(proto.getFamilyName()); this.profileKey = OptionalUtil.absentIfEmpty(proto.getProfileKey()); @@ -69,7 +70,7 @@ public final class SignalContactRecord implements SignalRecord { diff.add("E164"); } - if (!Objects.equals(this.getAddress().getUuid(), that.getAddress().getUuid())) { + if (!Objects.equals(this.getAddress().getAci(), that.getAddress().getAci())) { diff.add("UUID"); } @@ -211,7 +212,7 @@ public final class SignalContactRecord implements SignalRecord { this.id = StorageId.forContact(rawId); this.builder = ContactRecord.newBuilder(); - builder.setServiceUuid(address.getUuid().toString()); + builder.setServiceUuid(address.getAci().toString()); builder.setServiceE164(address.getNumber().or("")); } diff --git a/libsignal/service/src/main/java/org/whispersystems/signalservice/api/util/CredentialsProvider.java b/libsignal/service/src/main/java/org/whispersystems/signalservice/api/util/CredentialsProvider.java index 4d3cec8502..b4e522d4e5 100644 --- a/libsignal/service/src/main/java/org/whispersystems/signalservice/api/util/CredentialsProvider.java +++ b/libsignal/service/src/main/java/org/whispersystems/signalservice/api/util/CredentialsProvider.java @@ -6,10 +6,10 @@ package org.whispersystems.signalservice.api.util; -import java.util.UUID; +import org.whispersystems.signalservice.api.push.ACI; public interface CredentialsProvider { - public UUID getUuid(); - public String getE164(); - public String getPassword(); + ACI getAci(); + String getE164(); + String getPassword(); } diff --git a/libsignal/service/src/main/java/org/whispersystems/signalservice/api/util/UuidUtil.java b/libsignal/service/src/main/java/org/whispersystems/signalservice/api/util/UuidUtil.java index 0a304a61a7..470f208b04 100644 --- a/libsignal/service/src/main/java/org/whispersystems/signalservice/api/util/UuidUtil.java +++ b/libsignal/service/src/main/java/org/whispersystems/signalservice/api/util/UuidUtil.java @@ -72,7 +72,7 @@ public final class UuidUtil { return uuid != null ? uuid : UNKNOWN_UUID; } - private static UUID parseOrNull(byte[] byteArray) { + public static UUID parseOrNull(byte[] byteArray) { return byteArray != null && byteArray.length == 16 ? parseOrThrow(byteArray) : null; } diff --git a/libsignal/service/src/main/java/org/whispersystems/signalservice/internal/push/PushServiceSocket.java b/libsignal/service/src/main/java/org/whispersystems/signalservice/internal/push/PushServiceSocket.java index bc18e056de..2cb9ce162d 100644 --- a/libsignal/service/src/main/java/org/whispersystems/signalservice/internal/push/PushServiceSocket.java +++ b/libsignal/service/src/main/java/org/whispersystems/signalservice/internal/push/PushServiceSocket.java @@ -51,6 +51,7 @@ import org.whispersystems.signalservice.api.payments.CurrencyConversions; import org.whispersystems.signalservice.api.profiles.ProfileAndCredential; import org.whispersystems.signalservice.api.profiles.SignalServiceProfile; import org.whispersystems.signalservice.api.profiles.SignalServiceProfileWrite; +import org.whispersystems.signalservice.api.push.ACI; import org.whispersystems.signalservice.api.push.ContactTokenDetails; import org.whispersystems.signalservice.api.push.SignalServiceAddress; import org.whispersystems.signalservice.api.push.SignedPreKeyEntity; @@ -326,13 +327,13 @@ public class PushServiceSocket { makeServiceRequest(path, "GET", null, headers, new VerificationCodeResponseHandler()); } - public UUID getOwnUuid() throws IOException { + public ACI getOwnAci() throws IOException { String body = makeServiceRequest(WHO_AM_I, "GET", null); WhoAmIResponse response = JsonUtil.fromJson(body, WhoAmIResponse.class); - Optional uuid = UuidUtil.parse(response.getUuid()); + Optional aci = ACI.parse(response.getUuid()); - if (uuid.isPresent()) { - return uuid.get(); + if (aci.isPresent()) { + return aci.get(); } else { throw new IOException("Invalid UUID!"); } @@ -2086,7 +2087,7 @@ public class PushServiceSocket { private String getAuthorizationHeader(CredentialsProvider credentialsProvider) { try { - String identifier = credentialsProvider.getUuid() != null ? credentialsProvider.getUuid().toString() : credentialsProvider.getE164(); + String identifier = credentialsProvider.getAci() != null ? credentialsProvider.getAci().toString() : credentialsProvider.getE164(); return "Basic " + Base64.encodeBytes((identifier + ":" + credentialsProvider.getPassword()).getBytes("UTF-8")); } catch (UnsupportedEncodingException e) { throw new AssertionError(e); diff --git a/libsignal/service/src/main/java/org/whispersystems/signalservice/internal/push/SendGroupMessageResponse.java b/libsignal/service/src/main/java/org/whispersystems/signalservice/internal/push/SendGroupMessageResponse.java index e021087274..ec054dc598 100644 --- a/libsignal/service/src/main/java/org/whispersystems/signalservice/internal/push/SendGroupMessageResponse.java +++ b/libsignal/service/src/main/java/org/whispersystems/signalservice/internal/push/SendGroupMessageResponse.java @@ -3,6 +3,7 @@ package org.whispersystems.signalservice.internal.push; import com.fasterxml.jackson.annotation.JsonProperty; import org.whispersystems.libsignal.util.guava.Optional; +import org.whispersystems.signalservice.api.push.ACI; import org.whispersystems.signalservice.api.util.UuidUtil; import java.util.HashSet; @@ -16,16 +17,16 @@ public class SendGroupMessageResponse { public SendGroupMessageResponse() {} - public Set getUnsentTargets() { - Set uuids = new HashSet<>(uuids404.length); + public Set getUnsentTargets() { + Set acis = new HashSet<>(uuids404.length); for (String raw : uuids404) { - Optional parsed = UuidUtil.parse(raw); + Optional parsed = ACI.parse(raw); if (parsed.isPresent()) { - uuids.add(parsed.get()); + acis.add(parsed.get()); } } - return uuids; + return acis; } } diff --git a/libsignal/service/src/main/java/org/whispersystems/signalservice/internal/serialize/SignalServiceAddressProtobufSerializer.java b/libsignal/service/src/main/java/org/whispersystems/signalservice/internal/serialize/SignalServiceAddressProtobufSerializer.java index bb90748bd7..4f9f517941 100644 --- a/libsignal/service/src/main/java/org/whispersystems/signalservice/internal/serialize/SignalServiceAddressProtobufSerializer.java +++ b/libsignal/service/src/main/java/org/whispersystems/signalservice/internal/serialize/SignalServiceAddressProtobufSerializer.java @@ -1,14 +1,10 @@ package org.whispersystems.signalservice.internal.serialize; -import com.google.protobuf.ByteString; - import org.whispersystems.libsignal.util.guava.Optional; +import org.whispersystems.signalservice.api.push.ACI; import org.whispersystems.signalservice.api.push.SignalServiceAddress; -import org.whispersystems.signalservice.api.util.UuidUtil; import org.whispersystems.signalservice.internal.serialize.protos.AddressProto; -import java.util.UUID; - public final class SignalServiceAddressProtobufSerializer { private SignalServiceAddressProtobufSerializer() { @@ -17,7 +13,7 @@ public final class SignalServiceAddressProtobufSerializer { public static AddressProto toProtobuf(SignalServiceAddress signalServiceAddress) { AddressProto.Builder builder = AddressProto.newBuilder(); - builder.setUuid(ByteString.copyFrom(UuidUtil.toByteArray(signalServiceAddress.getUuid()))); + builder.setUuid(signalServiceAddress.getAci().toByteString()); if(signalServiceAddress.getNumber().isPresent()){ builder.setE164(signalServiceAddress.getNumber().get()); @@ -27,9 +23,9 @@ public final class SignalServiceAddressProtobufSerializer { } public static SignalServiceAddress fromProtobuf(AddressProto addressProto) { - UUID uuid = UuidUtil.parseOrThrow(addressProto.getUuid().toByteArray()); + ACI aci = ACI.parseOrThrow(addressProto.getUuid().toByteArray()); Optional number = addressProto.hasE164() ? Optional.of(addressProto.getE164()) : Optional.absent(); - return new SignalServiceAddress(uuid, number); + return new SignalServiceAddress(aci, number); } } diff --git a/libsignal/service/src/main/java/org/whispersystems/signalservice/internal/util/JsonUtil.java b/libsignal/service/src/main/java/org/whispersystems/signalservice/internal/util/JsonUtil.java index 243a21af63..239043ffc0 100644 --- a/libsignal/service/src/main/java/org/whispersystems/signalservice/internal/util/JsonUtil.java +++ b/libsignal/service/src/main/java/org/whispersystems/signalservice/internal/util/JsonUtil.java @@ -21,6 +21,7 @@ import com.fasterxml.jackson.databind.SerializerProvider; import org.whispersystems.libsignal.IdentityKey; import org.whispersystems.libsignal.InvalidKeyException; import org.whispersystems.libsignal.logging.Log; +import org.whispersystems.signalservice.api.push.ACI; import org.whispersystems.signalservice.api.push.exceptions.MalformedResponseException; import org.whispersystems.signalservice.api.util.UuidUtil; import org.whispersystems.util.Base64; @@ -113,4 +114,20 @@ public class JsonUtil { return UuidUtil.parseOrNull(p.getValueAsString()); } } + + public static class AciSerializer extends JsonSerializer { + @Override + public void serialize(ACI value, JsonGenerator gen, SerializerProvider serializers) + throws IOException + { + gen.writeString(value.toString()); + } + } + + public static class AciDeserializer extends JsonDeserializer { + @Override + public ACI deserialize(JsonParser p, DeserializationContext ctxt) throws IOException { + return ACI.parseOrNull(p.getValueAsString()); + } + } } diff --git a/libsignal/service/src/main/java/org/whispersystems/signalservice/internal/util/StaticCredentialsProvider.java b/libsignal/service/src/main/java/org/whispersystems/signalservice/internal/util/StaticCredentialsProvider.java index 828adc0753..a1206cc853 100644 --- a/libsignal/service/src/main/java/org/whispersystems/signalservice/internal/util/StaticCredentialsProvider.java +++ b/libsignal/service/src/main/java/org/whispersystems/signalservice/internal/util/StaticCredentialsProvider.java @@ -6,25 +6,24 @@ package org.whispersystems.signalservice.internal.util; +import org.whispersystems.signalservice.api.push.ACI; import org.whispersystems.signalservice.api.util.CredentialsProvider; -import java.util.UUID; - public class StaticCredentialsProvider implements CredentialsProvider { - private final UUID uuid; + private final ACI aci; private final String e164; private final String password; - public StaticCredentialsProvider(UUID uuid, String e164, String password) { - this.uuid = uuid; - this.e164 = e164; - this.password = password; + public StaticCredentialsProvider(ACI aci, String e164, String password) { + this.aci = aci; + this.e164 = e164; + this.password = password; } @Override - public UUID getUuid() { - return uuid; + public ACI getAci() { + return aci; } @Override diff --git a/libsignal/service/src/main/java/org/whispersystems/signalservice/internal/websocket/WebSocketConnection.java b/libsignal/service/src/main/java/org/whispersystems/signalservice/internal/websocket/WebSocketConnection.java index 60ba39e743..b43f78637f 100644 --- a/libsignal/service/src/main/java/org/whispersystems/signalservice/internal/websocket/WebSocketConnection.java +++ b/libsignal/service/src/main/java/org/whispersystems/signalservice/internal/websocket/WebSocketConnection.java @@ -112,7 +112,7 @@ public class WebSocketConnection extends WebSocketListener { String filledUri; if (credentialsProvider.isPresent()) { - String identifier = Objects.requireNonNull(credentialsProvider.get().getUuid()).toString(); + String identifier = Objects.requireNonNull(credentialsProvider.get().getAci()).toString(); filledUri = String.format(wsUri, identifier, credentialsProvider.get().getPassword()); } else { filledUri = wsUri; diff --git a/libsignal/service/src/test/java/org/whispersystems/signalservice/api/storage/SignalContactRecordTest.java b/libsignal/service/src/test/java/org/whispersystems/signalservice/api/storage/SignalContactRecordTest.java index 69e7ac3fc9..dddaf57244 100644 --- a/libsignal/service/src/test/java/org/whispersystems/signalservice/api/storage/SignalContactRecordTest.java +++ b/libsignal/service/src/test/java/org/whispersystems/signalservice/api/storage/SignalContactRecordTest.java @@ -1,17 +1,16 @@ package org.whispersystems.signalservice.api.storage; import org.junit.Test; +import org.whispersystems.signalservice.api.push.ACI; import org.whispersystems.signalservice.api.push.SignalServiceAddress; import org.whispersystems.signalservice.api.util.UuidUtil; -import java.util.UUID; - import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNotEquals; public class SignalContactRecordTest { - private static final UUID UUID_A = UuidUtil.parseOrThrow("ebef429e-695e-4f51-bcc4-526a60ac68c7"); + private static final ACI ACI_A = ACI.parseOrThrow("ebef429e-695e-4f51-bcc4-526a60ac68c7"); private static final String E164_A = "+16108675309"; @Test @@ -19,8 +18,8 @@ public class SignalContactRecordTest { byte[] profileKey = new byte[32]; byte[] profileKeyCopy = profileKey.clone(); - SignalContactRecord a = contactBuilder(1, UUID_A, E164_A, "a").setIdentityKey(profileKey).build(); - SignalContactRecord b = contactBuilder(1, UUID_A, E164_A, "a").setIdentityKey(profileKeyCopy).build(); + SignalContactRecord a = contactBuilder(1, ACI_A, E164_A, "a").setIdentityKey(profileKey).build(); + SignalContactRecord b = contactBuilder(1, ACI_A, E164_A, "a").setIdentityKey(profileKeyCopy).build(); assertEquals(a, b); assertEquals(a.hashCode(), b.hashCode()); @@ -32,8 +31,8 @@ public class SignalContactRecordTest { byte[] profileKeyCopy = profileKey.clone(); profileKeyCopy[0] = 1; - SignalContactRecord a = contactBuilder(1, UUID_A, E164_A, "a").setIdentityKey(profileKey).build(); - SignalContactRecord b = contactBuilder(1, UUID_A, E164_A, "a").setIdentityKey(profileKeyCopy).build(); + SignalContactRecord a = contactBuilder(1, ACI_A, E164_A, "a").setIdentityKey(profileKey).build(); + SignalContactRecord b = contactBuilder(1, ACI_A, E164_A, "a").setIdentityKey(profileKeyCopy).build(); assertNotEquals(a, b); assertNotEquals(a.hashCode(), b.hashCode()); @@ -49,11 +48,11 @@ public class SignalContactRecordTest { } private static SignalContactRecord.Builder contactBuilder(int key, - UUID uuid, + ACI aci, String e164, String givenName) { - return new SignalContactRecord.Builder(byteArray(key), new SignalServiceAddress(uuid, e164)) + return new SignalContactRecord.Builder(byteArray(key), new SignalServiceAddress(aci, e164)) .setGivenName(givenName); } } diff --git a/libsignal/service/src/test/java/org/whispersystems/signalservice/internal/serialize/SignalServiceAddressProtobufSerializerTest.java b/libsignal/service/src/test/java/org/whispersystems/signalservice/internal/serialize/SignalServiceAddressProtobufSerializerTest.java index 2438467638..38761fb3e5 100644 --- a/libsignal/service/src/test/java/org/whispersystems/signalservice/internal/serialize/SignalServiceAddressProtobufSerializerTest.java +++ b/libsignal/service/src/test/java/org/whispersystems/signalservice/internal/serialize/SignalServiceAddressProtobufSerializerTest.java @@ -2,6 +2,7 @@ package org.whispersystems.signalservice.internal.serialize; import org.junit.Test; import org.whispersystems.libsignal.util.guava.Optional; +import org.whispersystems.signalservice.api.push.ACI; import org.whispersystems.signalservice.api.push.SignalServiceAddress; import org.whispersystems.signalservice.internal.serialize.protos.AddressProto; @@ -13,7 +14,7 @@ public final class SignalServiceAddressProtobufSerializerTest { @Test public void serialize_and_deserialize_uuid_address() { - SignalServiceAddress address = new SignalServiceAddress(UUID.randomUUID(), Optional.absent()); + SignalServiceAddress address = new SignalServiceAddress(ACI.from(UUID.randomUUID()), Optional.absent()); AddressProto addressProto = org.whispersystems.signalservice.internal.serialize.SignalServiceAddressProtobufSerializer.toProtobuf(address); SignalServiceAddress deserialized = org.whispersystems.signalservice.internal.serialize.SignalServiceAddressProtobufSerializer.fromProtobuf(addressProto); @@ -22,7 +23,7 @@ public final class SignalServiceAddressProtobufSerializerTest { @Test public void serialize_and_deserialize_both_address() { - SignalServiceAddress address = new SignalServiceAddress(UUID.randomUUID(), Optional.of("+15552345678")); + SignalServiceAddress address = new SignalServiceAddress(ACI.from(UUID.randomUUID()), Optional.of("+15552345678")); AddressProto addressProto = org.whispersystems.signalservice.internal.serialize.SignalServiceAddressProtobufSerializer.toProtobuf(address); SignalServiceAddress deserialized = org.whispersystems.signalservice.internal.serialize.SignalServiceAddressProtobufSerializer.fromProtobuf(addressProto);