Move from ACI to a generic ServiceId.
This commit is contained in:
parent
9f1deda220
commit
7ca2420287
110 changed files with 841 additions and 824 deletions
|
@ -117,6 +117,48 @@ android {
|
|||
}
|
||||
}
|
||||
|
||||
testOptions {
|
||||
execution 'ANDROIDX_TEST_ORCHESTRATOR'
|
||||
|
||||
unitTests {
|
||||
includeAndroidResources = true
|
||||
}
|
||||
}
|
||||
|
||||
lintOptions {
|
||||
checkReleaseBuilds false
|
||||
abortOnError true
|
||||
baseline file("lint-baseline.xml")
|
||||
disable "LintError"
|
||||
}
|
||||
|
||||
sourceSets {
|
||||
test {
|
||||
java.srcDirs += "$projectDir/src/testShared"
|
||||
}
|
||||
|
||||
androidTest {
|
||||
java.srcDirs += "$projectDir/src/testShared"
|
||||
}
|
||||
}
|
||||
|
||||
compileOptions {
|
||||
coreLibraryDesugaringEnabled true
|
||||
sourceCompatibility JAVA_VERSION
|
||||
targetCompatibility JAVA_VERSION
|
||||
}
|
||||
|
||||
packagingOptions {
|
||||
exclude 'LICENSE.txt'
|
||||
exclude 'LICENSE'
|
||||
exclude 'NOTICE'
|
||||
exclude 'asm-license.txt'
|
||||
exclude 'META-INF/LICENSE'
|
||||
exclude 'META-INF/NOTICE'
|
||||
exclude 'META-INF/proguard/androidx-annotations.pro'
|
||||
}
|
||||
|
||||
|
||||
defaultConfig {
|
||||
versionCode canonicalVersionCode * postFixSize
|
||||
versionName canonicalVersionName
|
||||
|
@ -190,36 +232,6 @@ android {
|
|||
testInstrumentationRunnerArguments clearPackageData: 'true'
|
||||
}
|
||||
|
||||
testOptions {
|
||||
execution 'ANDROIDX_TEST_ORCHESTRATOR'
|
||||
}
|
||||
|
||||
sourceSets {
|
||||
test {
|
||||
java.srcDirs += "$projectDir/src/testShared"
|
||||
}
|
||||
|
||||
androidTest {
|
||||
java.srcDirs += "$projectDir/src/testShared"
|
||||
}
|
||||
}
|
||||
|
||||
compileOptions {
|
||||
coreLibraryDesugaringEnabled true
|
||||
sourceCompatibility JAVA_VERSION
|
||||
targetCompatibility JAVA_VERSION
|
||||
}
|
||||
|
||||
packagingOptions {
|
||||
exclude 'LICENSE.txt'
|
||||
exclude 'LICENSE'
|
||||
exclude 'NOTICE'
|
||||
exclude 'asm-license.txt'
|
||||
exclude 'META-INF/LICENSE'
|
||||
exclude 'META-INF/NOTICE'
|
||||
exclude 'META-INF/proguard/androidx-annotations.pro'
|
||||
}
|
||||
|
||||
buildTypes {
|
||||
debug {
|
||||
if (keystores['debug'] != null) {
|
||||
|
@ -371,19 +383,6 @@ android {
|
|||
variant.setIgnore(true)
|
||||
}
|
||||
}
|
||||
|
||||
lintOptions {
|
||||
checkReleaseBuilds false
|
||||
abortOnError true
|
||||
baseline file("lint-baseline.xml")
|
||||
disable "LintError"
|
||||
}
|
||||
|
||||
testOptions {
|
||||
unitTests {
|
||||
includeAndroidResources = true
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
dependencies {
|
||||
|
|
|
@ -4,7 +4,6 @@ import androidx.test.ext.junit.runners.AndroidJUnit4
|
|||
import org.junit.Assert.assertEquals
|
||||
import org.junit.Assert.assertFalse
|
||||
import org.junit.Assert.assertNotEquals
|
||||
import org.junit.Assert.assertNull
|
||||
import org.junit.Assert.assertTrue
|
||||
import org.junit.Before
|
||||
import org.junit.Test
|
||||
|
@ -30,8 +29,8 @@ class RecipientDatabaseTest {
|
|||
|
||||
private lateinit var recipientDatabase: RecipientDatabase
|
||||
|
||||
private val localAci = ACI.from(UUID.randomUUID());
|
||||
private val localPni = PNI.from(UUID.randomUUID());
|
||||
private val localAci = ACI.from(UUID.randomUUID())
|
||||
private val localPni = PNI.from(UUID.randomUUID())
|
||||
|
||||
@Before
|
||||
fun setup() {
|
||||
|
@ -52,7 +51,7 @@ class RecipientDatabaseTest {
|
|||
val recipientId: RecipientId = recipientDatabase.getAndPossiblyMerge(ACI_A, null, true)
|
||||
|
||||
val recipient = Recipient.resolved(recipientId)
|
||||
assertEquals(ACI_A, recipient.requireAci())
|
||||
assertEquals(ACI_A, recipient.requireServiceId())
|
||||
assertFalse(recipient.hasE164())
|
||||
}
|
||||
|
||||
|
@ -62,7 +61,7 @@ class RecipientDatabaseTest {
|
|||
val recipientId: RecipientId = recipientDatabase.getAndPossiblyMerge(ACI_A, null, false)
|
||||
|
||||
val recipient = Recipient.resolved(recipientId)
|
||||
assertEquals(ACI_A, recipient.requireAci())
|
||||
assertEquals(ACI_A, recipient.requireServiceId())
|
||||
assertFalse(recipient.hasE164())
|
||||
}
|
||||
|
||||
|
@ -73,7 +72,7 @@ class RecipientDatabaseTest {
|
|||
|
||||
val recipient = Recipient.resolved(recipientId)
|
||||
assertEquals(E164_A, recipient.requireE164())
|
||||
assertFalse(recipient.hasAci())
|
||||
assertFalse(recipient.hasServiceId())
|
||||
}
|
||||
|
||||
/** If all you have is an E164, you can just store that, regardless of trust level. */
|
||||
|
@ -83,7 +82,7 @@ class RecipientDatabaseTest {
|
|||
|
||||
val recipient = Recipient.resolved(recipientId)
|
||||
assertEquals(E164_A, recipient.requireE164())
|
||||
assertFalse(recipient.hasAci())
|
||||
assertFalse(recipient.hasServiceId())
|
||||
}
|
||||
|
||||
/** With high trust, you can associate an ACI-e164 pair. */
|
||||
|
@ -92,7 +91,7 @@ class RecipientDatabaseTest {
|
|||
val recipientId: RecipientId = recipientDatabase.getAndPossiblyMerge(ACI_A, E164_A, true)
|
||||
|
||||
val recipient = Recipient.resolved(recipientId)
|
||||
assertEquals(ACI_A, recipient.requireAci())
|
||||
assertEquals(ACI_A, recipient.requireServiceId())
|
||||
assertEquals(E164_A, recipient.requireE164())
|
||||
}
|
||||
|
||||
|
@ -102,7 +101,7 @@ class RecipientDatabaseTest {
|
|||
val recipientId: RecipientId = recipientDatabase.getAndPossiblyMerge(ACI_A, E164_A, false)
|
||||
|
||||
val recipient = Recipient.resolved(recipientId)
|
||||
assertEquals(ACI_A, recipient.requireAci())
|
||||
assertEquals(ACI_A, recipient.requireServiceId())
|
||||
assertFalse(recipient.hasE164())
|
||||
}
|
||||
|
||||
|
@ -113,26 +112,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.getOrInsertFromAci(ACI_A)
|
||||
val existingId: RecipientId = recipientDatabase.getOrInsertFromServiceId(ACI_A)
|
||||
|
||||
val retrievedId: RecipientId = recipientDatabase.getAndPossiblyMerge(ACI_A, E164_A, true)
|
||||
assertEquals(existingId, retrievedId)
|
||||
|
||||
val retrievedRecipient = Recipient.resolved(retrievedId)
|
||||
assertEquals(ACI_A, retrievedRecipient.requireAci())
|
||||
assertEquals(ACI_A, retrievedRecipient.requireServiceId())
|
||||
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.getOrInsertFromAci(ACI_A)
|
||||
val existingId: RecipientId = recipientDatabase.getOrInsertFromServiceId(ACI_A)
|
||||
|
||||
val retrievedId: RecipientId = recipientDatabase.getAndPossiblyMerge(ACI_A, E164_A, false)
|
||||
assertEquals(existingId, retrievedId)
|
||||
|
||||
val retrievedRecipient = Recipient.resolved(retrievedId)
|
||||
assertEquals(ACI_A, retrievedRecipient.requireAci())
|
||||
assertEquals(ACI_A, retrievedRecipient.requireServiceId())
|
||||
assertFalse(retrievedRecipient.hasE164())
|
||||
}
|
||||
|
||||
|
@ -145,7 +144,7 @@ class RecipientDatabaseTest {
|
|||
assertEquals(existingId, retrievedId)
|
||||
|
||||
val retrievedRecipient = Recipient.resolved(retrievedId)
|
||||
assertEquals(ACI_A, retrievedRecipient.requireAci())
|
||||
assertEquals(ACI_A, retrievedRecipient.requireServiceId())
|
||||
assertEquals(E164_B, retrievedRecipient.requireE164())
|
||||
}
|
||||
|
||||
|
@ -158,7 +157,7 @@ class RecipientDatabaseTest {
|
|||
assertEquals(existingId, retrievedId)
|
||||
|
||||
val retrievedRecipient = Recipient.resolved(retrievedId)
|
||||
assertEquals(ACI_A, retrievedRecipient.requireAci())
|
||||
assertEquals(ACI_A, retrievedRecipient.requireServiceId())
|
||||
assertEquals(E164_A, retrievedRecipient.requireE164())
|
||||
}
|
||||
|
||||
|
@ -175,7 +174,7 @@ class RecipientDatabaseTest {
|
|||
assertEquals(existingId, retrievedId)
|
||||
|
||||
val retrievedRecipient = Recipient.resolved(retrievedId)
|
||||
assertEquals(ACI_A, retrievedRecipient.requireAci())
|
||||
assertEquals(ACI_A, retrievedRecipient.requireServiceId())
|
||||
assertEquals(E164_A, retrievedRecipient.requireE164())
|
||||
}
|
||||
|
||||
|
@ -188,12 +187,12 @@ class RecipientDatabaseTest {
|
|||
assertNotEquals(existingId, retrievedId)
|
||||
|
||||
val retrievedRecipient = Recipient.resolved(retrievedId)
|
||||
assertEquals(ACI_A, retrievedRecipient.requireAci())
|
||||
assertEquals(ACI_A, retrievedRecipient.requireServiceId())
|
||||
assertFalse(retrievedRecipient.hasE164())
|
||||
|
||||
val existingRecipient = Recipient.resolved(existingId)
|
||||
assertEquals(E164_A, existingRecipient.requireE164())
|
||||
assertFalse(existingRecipient.hasAci())
|
||||
assertFalse(existingRecipient.hasServiceId())
|
||||
}
|
||||
|
||||
/** 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. */
|
||||
|
@ -207,14 +206,12 @@ class RecipientDatabaseTest {
|
|||
assertNotEquals(existingId, retrievedId)
|
||||
|
||||
val retrievedRecipient = Recipient.resolved(retrievedId)
|
||||
assertEquals(ACI_B, retrievedRecipient.requireAci())
|
||||
assertEquals(ACI_B, retrievedRecipient.requireServiceId())
|
||||
assertEquals(E164_A, retrievedRecipient.requireE164())
|
||||
assertEquals(PNI_A, retrievedRecipient.pni.get())
|
||||
|
||||
val existingRecipient = Recipient.resolved(existingId)
|
||||
assertEquals(ACI_A, existingRecipient.requireAci())
|
||||
assertEquals(ACI_A, existingRecipient.requireServiceId())
|
||||
assertFalse(existingRecipient.hasE164())
|
||||
assertNull(existingRecipient.pni.orNull())
|
||||
}
|
||||
|
||||
/** We never change the ACI of an existing row. New ACI = new person, regardless of trust. And low trust means we can’t take the e164. */
|
||||
|
@ -226,11 +223,11 @@ class RecipientDatabaseTest {
|
|||
assertNotEquals(existingId, retrievedId)
|
||||
|
||||
val retrievedRecipient = Recipient.resolved(retrievedId)
|
||||
assertEquals(ACI_B, retrievedRecipient.requireAci())
|
||||
assertEquals(ACI_B, retrievedRecipient.requireServiceId())
|
||||
assertFalse(retrievedRecipient.hasE164())
|
||||
|
||||
val existingRecipient = Recipient.resolved(existingId)
|
||||
assertEquals(ACI_A, existingRecipient.requireAci())
|
||||
assertEquals(ACI_A, existingRecipient.requireServiceId())
|
||||
assertEquals(E164_A, existingRecipient.requireE164())
|
||||
}
|
||||
|
||||
|
@ -249,11 +246,11 @@ class RecipientDatabaseTest {
|
|||
assertNotEquals(existingId, retrievedId)
|
||||
|
||||
val retrievedRecipient = Recipient.resolved(retrievedId)
|
||||
assertEquals(ACI_B, retrievedRecipient.requireAci())
|
||||
assertEquals(ACI_B, retrievedRecipient.requireServiceId())
|
||||
assertFalse(retrievedRecipient.hasE164())
|
||||
|
||||
val existingRecipient = Recipient.resolved(existingId)
|
||||
assertEquals(ACI_A, existingRecipient.requireAci())
|
||||
assertEquals(ACI_A, existingRecipient.requireServiceId())
|
||||
assertEquals(E164_A, existingRecipient.requireE164())
|
||||
}
|
||||
|
||||
|
@ -270,7 +267,7 @@ class RecipientDatabaseTest {
|
|||
assertEquals(existingId, retrievedId)
|
||||
|
||||
val retrievedRecipient = Recipient.resolved(retrievedId)
|
||||
assertEquals(ACI_A, retrievedRecipient.requireAci())
|
||||
assertEquals(ACI_A, retrievedRecipient.requireServiceId())
|
||||
assertEquals(E164_A, retrievedRecipient.requireE164())
|
||||
}
|
||||
|
||||
|
@ -287,7 +284,7 @@ class RecipientDatabaseTest {
|
|||
assertEquals(existingAciId, retrievedId)
|
||||
|
||||
val retrievedRecipient = Recipient.resolved(retrievedId)
|
||||
assertEquals(ACI_A, retrievedRecipient.requireAci())
|
||||
assertEquals(ACI_A, retrievedRecipient.requireServiceId())
|
||||
assertEquals(E164_A, retrievedRecipient.requireE164())
|
||||
|
||||
val existingE164Recipient = Recipient.resolved(existingE164Id)
|
||||
|
@ -310,7 +307,7 @@ class RecipientDatabaseTest {
|
|||
assertEquals(existingAciId, retrievedId)
|
||||
|
||||
val retrievedRecipient = Recipient.resolved(retrievedId)
|
||||
assertEquals(ACI_A, retrievedRecipient.requireAci())
|
||||
assertEquals(ACI_A, retrievedRecipient.requireServiceId())
|
||||
assertEquals(E164_A, retrievedRecipient.requireE164())
|
||||
|
||||
val existingE164Recipient = Recipient.resolved(existingE164Id)
|
||||
|
@ -323,19 +320,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.getOrInsertFromAci(ACI_A)
|
||||
val existingAciId: RecipientId = recipientDatabase.getOrInsertFromServiceId(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.requireAci())
|
||||
assertEquals(ACI_A, retrievedRecipient.requireServiceId())
|
||||
assertFalse(retrievedRecipient.hasE164())
|
||||
|
||||
val existingE164Recipient = Recipient.resolved(existingE164Id)
|
||||
assertEquals(E164_A, existingE164Recipient.requireE164())
|
||||
assertFalse(existingE164Recipient.hasAci())
|
||||
assertFalse(existingE164Recipient.hasServiceId())
|
||||
}
|
||||
|
||||
/** Another high trust case. No new rules here, just a more complex scenario to show how different rules interact. */
|
||||
|
@ -351,11 +348,11 @@ class RecipientDatabaseTest {
|
|||
assertEquals(existingId1, retrievedId)
|
||||
|
||||
val retrievedRecipient = Recipient.resolved(retrievedId)
|
||||
assertEquals(ACI_A, retrievedRecipient.requireAci())
|
||||
assertEquals(ACI_A, retrievedRecipient.requireServiceId())
|
||||
assertEquals(E164_A, retrievedRecipient.requireE164())
|
||||
|
||||
val existingRecipient2 = Recipient.resolved(existingId2)
|
||||
assertEquals(ACI_B, existingRecipient2.requireAci())
|
||||
assertEquals(ACI_B, existingRecipient2.requireServiceId())
|
||||
assertFalse(existingRecipient2.hasE164())
|
||||
|
||||
assert(changeNumberListener.numberChangeWasEnqueued)
|
||||
|
@ -371,11 +368,11 @@ class RecipientDatabaseTest {
|
|||
assertEquals(existingId1, retrievedId)
|
||||
|
||||
val retrievedRecipient = Recipient.resolved(retrievedId)
|
||||
assertEquals(ACI_A, retrievedRecipient.requireAci())
|
||||
assertEquals(ACI_A, retrievedRecipient.requireServiceId())
|
||||
assertEquals(E164_B, retrievedRecipient.requireE164())
|
||||
|
||||
val existingRecipient2 = Recipient.resolved(existingId2)
|
||||
assertEquals(ACI_B, existingRecipient2.requireAci())
|
||||
assertEquals(ACI_B, existingRecipient2.requireServiceId())
|
||||
assertEquals(E164_A, existingRecipient2.requireE164())
|
||||
}
|
||||
|
||||
|
@ -392,7 +389,7 @@ class RecipientDatabaseTest {
|
|||
assertEquals(existingId1, retrievedId)
|
||||
|
||||
val retrievedRecipient = Recipient.resolved(retrievedId)
|
||||
assertEquals(ACI_A, retrievedRecipient.requireAci())
|
||||
assertEquals(ACI_A, retrievedRecipient.requireServiceId())
|
||||
assertEquals(E164_A, retrievedRecipient.requireE164())
|
||||
|
||||
assertFalse(recipientDatabase.getByE164(E164_B).isPresent)
|
||||
|
@ -417,11 +414,11 @@ class RecipientDatabaseTest {
|
|||
assertEquals(existingId2, retrievedId)
|
||||
|
||||
val retrievedRecipient = Recipient.resolved(retrievedId)
|
||||
assertEquals(ACI_A, retrievedRecipient.requireAci())
|
||||
assertEquals(ACI_A, retrievedRecipient.requireServiceId())
|
||||
assertFalse(retrievedRecipient.hasE164())
|
||||
|
||||
val recipientWithId1 = Recipient.resolved(existingId1)
|
||||
assertEquals(ACI_B, recipientWithId1.requireAci())
|
||||
assertEquals(ACI_B, recipientWithId1.requireServiceId())
|
||||
assertEquals(E164_A, recipientWithId1.requireE164())
|
||||
}
|
||||
|
||||
|
@ -440,7 +437,7 @@ class RecipientDatabaseTest {
|
|||
assertEquals(existingId, retrievedId)
|
||||
|
||||
val retrievedRecipient = Recipient.resolved(retrievedId)
|
||||
assertEquals(ACI_A, retrievedRecipient.requireAci())
|
||||
assertEquals(ACI_A, retrievedRecipient.requireServiceId())
|
||||
assertEquals(E164_A, retrievedRecipient.requireE164())
|
||||
}
|
||||
|
||||
|
@ -459,7 +456,7 @@ class RecipientDatabaseTest {
|
|||
assertEquals(existingId, retrievedId)
|
||||
|
||||
val retrievedRecipient = Recipient.resolved(retrievedId)
|
||||
assertEquals(ACI_A, retrievedRecipient.requireAci())
|
||||
assertEquals(ACI_A, retrievedRecipient.requireServiceId())
|
||||
assertEquals(E164_B, retrievedRecipient.requireE164())
|
||||
}
|
||||
|
||||
|
@ -475,7 +472,7 @@ class RecipientDatabaseTest {
|
|||
assertEquals(existingId, retrievedId)
|
||||
|
||||
val retrievedRecipient = Recipient.resolved(retrievedId)
|
||||
assertEquals(ACI_A, retrievedRecipient.requireAci())
|
||||
assertEquals(ACI_A, retrievedRecipient.requireServiceId())
|
||||
assertEquals(E164_B, retrievedRecipient.requireE164())
|
||||
|
||||
changeNumberListener.waitForJobManager()
|
||||
|
@ -506,18 +503,18 @@ class RecipientDatabaseTest {
|
|||
@Test
|
||||
fun createByUuidSanityCheck() {
|
||||
// GIVEN one recipient
|
||||
val recipientId: RecipientId = recipientDatabase.getOrInsertFromAci(ACI_A)
|
||||
val recipientId: RecipientId = recipientDatabase.getOrInsertFromServiceId(ACI_A)
|
||||
|
||||
// WHEN I retrieve one by UUID
|
||||
val possible: Optional<RecipientId> = recipientDatabase.getByAci(ACI_A)
|
||||
val possible: Optional<RecipientId> = recipientDatabase.getByServiceId(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.aci.isPresent)
|
||||
assertEquals(ACI_A, recipient.aci.get())
|
||||
assertTrue(recipient.serviceId.isPresent)
|
||||
assertEquals(ACI_A, recipient.serviceId.get())
|
||||
}
|
||||
|
||||
@Test(expected = IllegalArgumentException::class)
|
||||
|
|
|
@ -53,8 +53,8 @@ class RecipientDatabaseTest_merges {
|
|||
private lateinit var reactionDatabase: ReactionDatabase
|
||||
private lateinit var notificationProfileDatabase: NotificationProfileDatabase
|
||||
|
||||
private val localAci = ACI.from(UUID.randomUUID());
|
||||
private val localPni = PNI.from(UUID.randomUUID());
|
||||
private val localAci = ACI.from(UUID.randomUUID())
|
||||
private val localPni = PNI.from(UUID.randomUUID())
|
||||
|
||||
@Before
|
||||
fun setup() {
|
||||
|
@ -80,9 +80,9 @@ class RecipientDatabaseTest_merges {
|
|||
@Test
|
||||
fun getAndPossiblyMerge_general() {
|
||||
// Setup
|
||||
val recipientIdAci: RecipientId = recipientDatabase.getOrInsertFromAci(ACI_A)
|
||||
val recipientIdAci: RecipientId = recipientDatabase.getOrInsertFromServiceId(ACI_A)
|
||||
val recipientIdE164: RecipientId = recipientDatabase.getOrInsertFromE164(E164_A)
|
||||
val recipientIdAciB: RecipientId = recipientDatabase.getOrInsertFromAci(ACI_B)
|
||||
val recipientIdAciB: RecipientId = recipientDatabase.getOrInsertFromServiceId(ACI_B)
|
||||
|
||||
val smsId1: Long = smsDatabase.insertMessageInbox(smsMessage(sender = recipientIdAci, time = 0, body = "0")).get().messageId
|
||||
val smsId2: Long = smsDatabase.insertMessageInbox(smsMessage(sender = recipientIdE164, time = 1, body = "1")).get().messageId
|
||||
|
@ -127,7 +127,7 @@ class RecipientDatabaseTest_merges {
|
|||
|
||||
// Recipient validation
|
||||
val retrievedRecipient = Recipient.resolved(retrievedId)
|
||||
assertEquals(ACI_A, retrievedRecipient.requireAci())
|
||||
assertEquals(ACI_A, retrievedRecipient.requireServiceId())
|
||||
assertEquals(E164_A, retrievedRecipient.requireE164())
|
||||
|
||||
val existingE164Recipient = Recipient.resolved(recipientIdE164)
|
||||
|
|
|
@ -571,11 +571,11 @@ public final class ContactSelectionListFragment extends LoggingFragment
|
|||
AlertDialog loadingDialog = SimpleProgressDialog.show(requireContext());
|
||||
|
||||
SimpleTask.run(getViewLifecycleOwner().getLifecycle(), () -> {
|
||||
return UsernameUtil.fetchAciForUsername(requireContext(), contact.getNumber());
|
||||
return UsernameUtil.fetchAciForUsername(contact.getNumber());
|
||||
}, uuid -> {
|
||||
loadingDialog.dismiss();
|
||||
if (uuid.isPresent()) {
|
||||
Recipient recipient = Recipient.externalUsername(requireContext(), uuid.get(), contact.getNumber());
|
||||
Recipient recipient = Recipient.externalUsername(uuid.get(), contact.getNumber());
|
||||
SelectedContact selected = SelectedContact.forUsername(recipient.getId(), contact.getNumber());
|
||||
|
||||
if (onContactSelectedListener != null) {
|
||||
|
|
|
@ -75,7 +75,7 @@ public class NewConversationActivity extends ContactSelectionActivity
|
|||
SimpleTask.run(getLifecycle(), () -> {
|
||||
Recipient resolved = Recipient.external(this, number);
|
||||
|
||||
if (!resolved.isRegistered() || !resolved.hasAci()) {
|
||||
if (!resolved.isRegistered() || !resolved.hasServiceId()) {
|
||||
Log.i(TAG, "[onContactSelected] Not registered or no UUID. Doing a directory refresh.");
|
||||
try {
|
||||
DirectoryHelper.refreshDirectoryFor(this, resolved, false);
|
||||
|
|
|
@ -26,8 +26,7 @@ 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 org.whispersystems.signalservice.api.push.PNI
|
||||
import org.whispersystems.signalservice.api.push.ServiceId
|
||||
import java.util.Objects
|
||||
|
||||
/**
|
||||
|
@ -61,18 +60,11 @@ class InternalConversationSettingsFragment : DSLSettingsFragment(
|
|||
)
|
||||
|
||||
if (!recipient.isGroup) {
|
||||
val aci = recipient.aci.transform(ACI::toString).or("null")
|
||||
val serviceId = recipient.serviceId.transform(ServiceId::toString).or("null")
|
||||
longClickPref(
|
||||
title = DSLSettingsText.from("ACI"),
|
||||
summary = DSLSettingsText.from(aci),
|
||||
onLongClick = { copyToClipboard(aci) }
|
||||
)
|
||||
|
||||
val pni = recipient.pni.transform(PNI::toString).or("null")
|
||||
longClickPref(
|
||||
title = DSLSettingsText.from("PNI"),
|
||||
summary = DSLSettingsText.from(pni),
|
||||
onLongClick = { copyToClipboard(pni) }
|
||||
title = DSLSettingsText.from("ServiceId"),
|
||||
summary = DSLSettingsText.from(serviceId),
|
||||
onLongClick = { copyToClipboard(serviceId) }
|
||||
)
|
||||
}
|
||||
|
||||
|
@ -153,17 +145,8 @@ class InternalConversationSettingsFragment : DSLSettingsFragment(
|
|||
.setTitle("Are you sure?")
|
||||
.setNegativeButton(android.R.string.cancel) { d, _ -> d.dismiss() }
|
||||
.setPositiveButton(android.R.string.ok) { _, _ ->
|
||||
if (recipient.hasAci()) {
|
||||
SignalDatabase.sessions.deleteAllFor(accountId = Recipient.self().requireAci(), addressName = recipient.requireAci().toString())
|
||||
SignalDatabase.sessions.deleteAllFor(accountId = Recipient.self().requirePni(), addressName = recipient.requireAci().toString())
|
||||
}
|
||||
if (recipient.hasE164()) {
|
||||
SignalDatabase.sessions.deleteAllFor(accountId = Recipient.self().requireAci(), addressName = recipient.requireE164())
|
||||
SignalDatabase.sessions.deleteAllFor(accountId = Recipient.self().requirePni(), addressName = recipient.requireE164())
|
||||
}
|
||||
if (recipient.hasPni()) {
|
||||
SignalDatabase.sessions.deleteAllFor(accountId = Recipient.self().requireAci(), addressName = recipient.requirePni().toString())
|
||||
SignalDatabase.sessions.deleteAllFor(accountId = Recipient.self().requirePni(), addressName = recipient.requirePni().toString())
|
||||
if (recipient.hasServiceId()) {
|
||||
SignalDatabase.sessions.deleteAllFor(serviceId = SignalStore.account().requireAci(), addressName = recipient.requireServiceId().toString())
|
||||
}
|
||||
}
|
||||
.show()
|
||||
|
|
|
@ -127,10 +127,10 @@ data class CallParticipantsState(
|
|||
fun getIncomingRingingGroupDescription(context: Context): String? {
|
||||
if (callState == WebRtcViewModel.State.CALL_INCOMING &&
|
||||
groupCallState == WebRtcViewModel.GroupCallState.RINGING &&
|
||||
ringerRecipient.hasAci()
|
||||
ringerRecipient.hasServiceId()
|
||||
) {
|
||||
val ringerName = ringerRecipient.getShortDisplayName(context)
|
||||
val membersWithoutYouOrRinger: List<GroupMemberEntry.FullMember> = groupMembers.filterNot { it.member.isSelf || ringerRecipient.requireAci() == it.member.aci.orNull() }
|
||||
val membersWithoutYouOrRinger: List<GroupMemberEntry.FullMember> = groupMembers.filterNot { it.member.isSelf || ringerRecipient.requireServiceId() == it.member.serviceId.orNull() }
|
||||
|
||||
return when (membersWithoutYouOrRinger.size) {
|
||||
0 -> context.getString(R.string.WebRtcCallView__s_is_calling_you, ringerName)
|
||||
|
|
|
@ -112,9 +112,9 @@ public class DirectoryHelper {
|
|||
RecipientDatabase recipientDatabase = SignalDatabase.recipients();
|
||||
|
||||
for (Recipient recipient : recipients) {
|
||||
if (recipient.hasAci() && !recipient.hasE164()) {
|
||||
if (ApplicationDependencies.getSignalServiceAccountManager().isIdentifierRegistered(recipient.requireAci())) {
|
||||
recipientDatabase.markRegistered(recipient.getId(), recipient.requireAci());
|
||||
if (recipient.hasServiceId() && !recipient.hasE164()) {
|
||||
if (ApplicationDependencies.getSignalServiceAccountManager().isIdentifierRegistered(recipient.requireServiceId())) {
|
||||
recipientDatabase.markRegistered(recipient.getId(), recipient.requireServiceId());
|
||||
} else {
|
||||
recipientDatabase.markUnregistered(recipient.getId());
|
||||
}
|
||||
|
@ -136,11 +136,11 @@ public class DirectoryHelper {
|
|||
RegisteredState originalRegisteredState = recipient.resolve().getRegistered();
|
||||
RegisteredState newRegisteredState;
|
||||
|
||||
if (recipient.hasAci() && !recipient.hasE164()) {
|
||||
boolean isRegistered = ApplicationDependencies.getSignalServiceAccountManager().isIdentifierRegistered(recipient.requireAci());
|
||||
if (recipient.hasServiceId() && !recipient.hasE164()) {
|
||||
boolean isRegistered = ApplicationDependencies.getSignalServiceAccountManager().isIdentifierRegistered(recipient.requireServiceId());
|
||||
stopwatch.split("aci-network");
|
||||
if (isRegistered) {
|
||||
boolean idChanged = recipientDatabase.markRegistered(recipient.getId(), recipient.requireAci());
|
||||
boolean idChanged = recipientDatabase.markRegistered(recipient.getId(), recipient.requireServiceId());
|
||||
if (idChanged) {
|
||||
Log.w(TAG, "ID changed during refresh by UUID.");
|
||||
}
|
||||
|
@ -173,14 +173,14 @@ public class DirectoryHelper {
|
|||
if (aci != null) {
|
||||
boolean idChanged = recipientDatabase.markRegistered(recipient.getId(), aci);
|
||||
if (idChanged) {
|
||||
recipient = Recipient.resolved(recipientDatabase.getByAci(aci).get());
|
||||
recipient = Recipient.resolved(recipientDatabase.getByServiceId(aci).get());
|
||||
}
|
||||
} else {
|
||||
Log.w(TAG, "Registered number set had a null ACI!");
|
||||
}
|
||||
} else if (recipient.hasAci() && recipient.isRegistered() && hasCommunicatedWith(recipient)) {
|
||||
if (ApplicationDependencies.getSignalServiceAccountManager().isIdentifierRegistered(recipient.requireAci())) {
|
||||
recipientDatabase.markRegistered(recipient.getId(), recipient.requireAci());
|
||||
} else if (recipient.hasServiceId() && recipient.isRegistered() && hasCommunicatedWith(recipient)) {
|
||||
if (ApplicationDependencies.getSignalServiceAccountManager().isIdentifierRegistered(recipient.requireServiceId())) {
|
||||
recipientDatabase.markRegistered(recipient.getId(), recipient.requireServiceId());
|
||||
} else {
|
||||
recipientDatabase.markUnregistered(recipient.getId());
|
||||
}
|
||||
|
@ -485,7 +485,13 @@ public class DirectoryHelper {
|
|||
}
|
||||
|
||||
public static boolean hasSession(@NonNull RecipientId id) {
|
||||
SignalProtocolAddress protocolAddress = new SignalProtocolAddress(Recipient.resolved(id).requireServiceId(), SignalServiceAddress.DEFAULT_DEVICE_ID);
|
||||
Recipient recipient = Recipient.resolved(id);
|
||||
|
||||
if (!recipient.hasServiceId()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
SignalProtocolAddress protocolAddress = Recipient.resolved(id).requireServiceId().toProtocolAddress(SignalServiceAddress.DEFAULT_DEVICE_ID);
|
||||
|
||||
return ApplicationDependencies.getProtocolStore().aci().containsSession(protocolAddress) ||
|
||||
ApplicationDependencies.getProtocolStore().pni().containsSession(protocolAddress);
|
||||
|
@ -511,7 +517,7 @@ public class DirectoryHelper {
|
|||
List<Recipient> possiblyUnlisted = Stream.of(inactiveIds)
|
||||
.map(Recipient::resolved)
|
||||
.filter(Recipient::isRegistered)
|
||||
.filter(Recipient::hasAci)
|
||||
.filter(Recipient::hasServiceId)
|
||||
.filter(DirectoryHelper::hasCommunicatedWith)
|
||||
.toList();
|
||||
|
||||
|
@ -546,12 +552,9 @@ public class DirectoryHelper {
|
|||
}
|
||||
|
||||
private static boolean hasCommunicatedWith(@NonNull Recipient recipient) {
|
||||
ACI localAci = Recipient.self().requireAci();
|
||||
ACI localAci = SignalStore.account().requireAci();
|
||||
|
||||
return SignalDatabase.threads().hasThread(recipient.getId()) ||
|
||||
(recipient.hasAci() && SignalDatabase.sessions().hasSessionFor(localAci, recipient.requireAci().toString())) ||
|
||||
(recipient.hasPni() && SignalDatabase.sessions().hasSessionFor(localAci, recipient.requirePni().toString())) ||
|
||||
(recipient.hasE164() && SignalDatabase.sessions().hasSessionFor(localAci, recipient.requireE164()));
|
||||
return SignalDatabase.threads().hasThread(recipient.getId()) || (recipient.hasServiceId() && SignalDatabase.sessions().hasSessionFor(localAci, recipient.requireServiceId().toString()));
|
||||
}
|
||||
|
||||
static class DirectoryResult {
|
||||
|
|
|
@ -1554,14 +1554,14 @@ public class ConversationParentFragment extends Fragment
|
|||
smsEnabled = false;
|
||||
}
|
||||
|
||||
if (!isSecureText && !isPushGroupConversation() && !recipient.get().isAciOnly() && !recipient.get().isReleaseNotes() && smsEnabled) {
|
||||
if (!isSecureText && !isPushGroupConversation() && !recipient.get().isServiceIdOnly() && !recipient.get().isReleaseNotes() && smsEnabled) {
|
||||
sendButton.disableTransport(Type.TEXTSECURE);
|
||||
}
|
||||
|
||||
if (!recipient.get().isPushGroup() && recipient.get().isForceSmsSelection() && smsEnabled) {
|
||||
sendButton.setDefaultTransport(Type.SMS);
|
||||
} else {
|
||||
if (isSecureText || isPushGroupConversation() || recipient.get().isAciOnly() || recipient.get().isReleaseNotes() || !smsEnabled) {
|
||||
if (isSecureText || isPushGroupConversation() || recipient.get().isServiceIdOnly() || recipient.get().isReleaseNotes() || !smsEnabled) {
|
||||
sendButton.setDefaultTransport(Type.TEXTSECURE);
|
||||
} else {
|
||||
sendButton.setDefaultTransport(Type.SMS);
|
||||
|
@ -3013,7 +3013,7 @@ public class ConversationParentFragment extends Fragment
|
|||
return new SettableFuture<>(null);
|
||||
}
|
||||
|
||||
final boolean sendPush = (isSecureText && !forceSms) || recipient.get().isAciOnly();
|
||||
final boolean sendPush = (isSecureText && !forceSms) || recipient.get().isServiceIdOnly();
|
||||
final long thread = this.threadId;
|
||||
|
||||
if (sendPush) {
|
||||
|
@ -3076,7 +3076,7 @@ public class ConversationParentFragment extends Fragment
|
|||
final long thread = this.threadId;
|
||||
final Context context = requireContext().getApplicationContext();
|
||||
final String messageBody = getMessage();
|
||||
final boolean sendPush = (isSecureText && !forceSms) || recipient.get().isAciOnly();
|
||||
final boolean sendPush = (isSecureText && !forceSms) || recipient.get().isServiceIdOnly();
|
||||
|
||||
OutgoingTextMessage message;
|
||||
|
||||
|
|
|
@ -7,7 +7,6 @@ import android.text.SpannableString;
|
|||
import android.util.AttributeSet;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.view.ViewTreeObserver;
|
||||
import android.widget.FrameLayout;
|
||||
import android.widget.TextView;
|
||||
|
||||
|
@ -52,6 +51,7 @@ 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 org.whispersystems.signalservice.api.push.ServiceId;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.Locale;
|
||||
|
@ -351,12 +351,12 @@ public final class ConversationUpdateItem extends FrameLayout
|
|||
}
|
||||
});
|
||||
} else if (conversationMessage.getMessageRecord().isGroupCall()) {
|
||||
UpdateDescription updateDescription = MessageRecord.getGroupCallUpdateDescription(getContext(), conversationMessage.getMessageRecord().getBody(), true);
|
||||
Collection<ACI> acis = updateDescription.getMentioned();
|
||||
UpdateDescription updateDescription = MessageRecord.getGroupCallUpdateDescription(getContext(), conversationMessage.getMessageRecord().getBody(), true);
|
||||
Collection<ServiceId> acis = updateDescription.getMentioned();
|
||||
|
||||
int text = 0;
|
||||
if (Util.hasItems(acis)) {
|
||||
if (acis.contains(Recipient.self().requireAci())) {
|
||||
if (acis.contains(Recipient.self().requireServiceId())) {
|
||||
text = R.string.ConversationUpdateItem_return_to_call;
|
||||
} else if (GroupCallUpdateDetailsUtil.parse(conversationMessage.getMessageRecord().getBody()).getIsCallFull()) {
|
||||
text = R.string.ConversationUpdateItem_call_is_full;
|
||||
|
|
|
@ -126,7 +126,7 @@ final class SafetyNumberChangeRepository {
|
|||
|
||||
try(SignalSessionLock.Lock unused = ReentrantSessionLock.INSTANCE.acquire()) {
|
||||
for (ChangedRecipient changedRecipient : changedRecipients) {
|
||||
SignalProtocolAddress mismatchAddress = new SignalProtocolAddress(changedRecipient.getRecipient().requireServiceId(), SignalServiceAddress.DEFAULT_DEVICE_ID);
|
||||
SignalProtocolAddress mismatchAddress = changedRecipient.getRecipient().requireServiceId().toProtocolAddress(SignalServiceAddress.DEFAULT_DEVICE_ID);
|
||||
|
||||
Log.d(TAG, "Saving identity for: " + changedRecipient.getRecipient().getId() + " " + changedRecipient.getIdentityRecord().getIdentityKey().hashCode());
|
||||
SignalIdentityKeyStore.SaveResult result = ApplicationDependencies.getProtocolStore().aci().identities().saveIdentity(mismatchAddress, changedRecipient.getIdentityRecord().getIdentityKey(), true);
|
||||
|
|
|
@ -22,7 +22,7 @@ public final class SenderKeyUtil {
|
|||
*/
|
||||
public static void rotateOurKey(@NonNull Context context, @NonNull DistributionId distributionId) {
|
||||
try (SignalSessionLock.Lock unused = ReentrantSessionLock.INSTANCE.acquire()) {
|
||||
ApplicationDependencies.getProtocolStore().aci().senderKeys().deleteAllFor(Recipient.self().requireServiceId(), distributionId);
|
||||
ApplicationDependencies.getProtocolStore().aci().senderKeys().deleteAllFor(SignalStore.account().requireAci().toString(), distributionId);
|
||||
SignalDatabase.senderKeyShared().deleteAllFor(distributionId);
|
||||
}
|
||||
}
|
||||
|
@ -31,7 +31,7 @@ public final class SenderKeyUtil {
|
|||
* Gets when the sender key session was created, or -1 if it doesn't exist.
|
||||
*/
|
||||
public static long getCreateTimeForOurKey(@NonNull Context context, @NonNull DistributionId distributionId) {
|
||||
SignalProtocolAddress address = new SignalProtocolAddress(Recipient.self().requireServiceId(), SignalStore.account().getDeviceId());
|
||||
SignalProtocolAddress address = new SignalProtocolAddress(SignalStore.account().requireAci().toString(), SignalStore.account().getDeviceId());
|
||||
return SignalDatabase.senderKeys().getCreatedTime(address, distributionId);
|
||||
}
|
||||
|
||||
|
|
|
@ -23,6 +23,7 @@ import org.whispersystems.libsignal.IdentityKey;
|
|||
import org.whispersystems.libsignal.SignalProtocolAddress;
|
||||
import org.whispersystems.libsignal.state.IdentityKeyStore;
|
||||
import org.whispersystems.libsignal.util.guava.Optional;
|
||||
import org.whispersystems.signalservice.api.push.ServiceId;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
@ -110,8 +111,8 @@ public class SignalBaseIdentityKeyStore {
|
|||
boolean nonBlockingApproval)
|
||||
{
|
||||
Recipient recipient = Recipient.resolved(recipientId);
|
||||
if (recipient.hasServiceIdentifier()) {
|
||||
cache.save(recipient.requireServiceId(), recipientId, identityKey, verifiedStatus, firstUse, timestamp, nonBlockingApproval);
|
||||
if (recipient.hasServiceId()) {
|
||||
cache.save(recipient.requireServiceId().toString(), recipientId, identityKey, verifiedStatus, firstUse, timestamp, nonBlockingApproval);
|
||||
} else {
|
||||
Log.w(TAG, "[saveIdentity] No serviceId for " + recipient.getId());
|
||||
}
|
||||
|
@ -120,7 +121,7 @@ public class SignalBaseIdentityKeyStore {
|
|||
public boolean isTrustedIdentity(SignalProtocolAddress address, IdentityKey identityKey, IdentityKeyStore.Direction direction) {
|
||||
Recipient self = Recipient.self();
|
||||
|
||||
boolean isSelf = address.getName().equals(self.requireAci().toString()) ||
|
||||
boolean isSelf = address.getName().equals(self.requireServiceId().toString()) ||
|
||||
address.getName().equals(self.requireE164());
|
||||
|
||||
if (isSelf) {
|
||||
|
@ -150,19 +151,20 @@ public class SignalBaseIdentityKeyStore {
|
|||
}
|
||||
|
||||
public @NonNull Optional<IdentityRecord> getIdentityRecord(@NonNull Recipient recipient) {
|
||||
if (recipient.hasServiceIdentifier()) {
|
||||
IdentityStoreRecord record = cache.get(recipient.requireServiceId());
|
||||
if (recipient.hasServiceId()) {
|
||||
IdentityStoreRecord record = cache.get(recipient.requireServiceId().toString());
|
||||
return Optional.fromNullable(record).transform(r -> r.toIdentityRecord(recipient.getId()));
|
||||
} else {
|
||||
Log.w(TAG, "[getIdentityRecord] No serviceId for " + recipient.getId());
|
||||
Log.w(TAG, "[getIdentityRecord] No ServiceId for " + recipient.getId());
|
||||
return Optional.absent();
|
||||
}
|
||||
}
|
||||
|
||||
public @NonNull IdentityRecordList getIdentityRecords(@NonNull List<Recipient> recipients) {
|
||||
List<String> addressNames = recipients.stream()
|
||||
.filter(Recipient::hasServiceIdentifier)
|
||||
.filter(Recipient::hasServiceId)
|
||||
.map(Recipient::requireServiceId)
|
||||
.map(ServiceId::toString)
|
||||
.collect(Collectors.toList());
|
||||
|
||||
if (addressNames.isEmpty()) {
|
||||
|
@ -172,8 +174,8 @@ public class SignalBaseIdentityKeyStore {
|
|||
List<IdentityRecord> records = new ArrayList<>(recipients.size());
|
||||
|
||||
for (Recipient recipient : recipients) {
|
||||
if (recipient.hasServiceIdentifier()) {
|
||||
IdentityStoreRecord record = cache.get(recipient.requireServiceId());
|
||||
if (recipient.hasServiceId()) {
|
||||
IdentityStoreRecord record = cache.get(recipient.requireServiceId().toString());
|
||||
|
||||
if (record != null) {
|
||||
records.add(record.toIdentityRecord(recipient.getId()));
|
||||
|
@ -189,8 +191,8 @@ public class SignalBaseIdentityKeyStore {
|
|||
public void setApproval(@NonNull RecipientId recipientId, boolean nonBlockingApproval) {
|
||||
Recipient recipient = Recipient.resolved(recipientId);
|
||||
|
||||
if (recipient.hasServiceIdentifier()) {
|
||||
cache.setApproval(recipient.requireServiceId(), recipientId, nonBlockingApproval);
|
||||
if (recipient.hasServiceId()) {
|
||||
cache.setApproval(recipient.requireServiceId().toString(), recipientId, nonBlockingApproval);
|
||||
} else {
|
||||
Log.w(TAG, "[setApproval] No serviceId for " + recipient.getId());
|
||||
}
|
||||
|
@ -199,8 +201,8 @@ public class SignalBaseIdentityKeyStore {
|
|||
public void setVerified(@NonNull RecipientId recipientId, IdentityKey identityKey, VerifiedStatus verifiedStatus) {
|
||||
Recipient recipient = Recipient.resolved(recipientId);
|
||||
|
||||
if (recipient.hasServiceIdentifier()) {
|
||||
cache.setVerified(recipient.requireServiceId(), recipientId, identityKey, verifiedStatus);
|
||||
if (recipient.hasServiceId()) {
|
||||
cache.setVerified(recipient.requireServiceId().toString(), recipientId, identityKey, verifiedStatus);
|
||||
} else {
|
||||
Log.w(TAG, "[setVerified] No serviceId for " + recipient.getId());
|
||||
}
|
||||
|
|
|
@ -7,7 +7,7 @@ import androidx.annotation.NonNull;
|
|||
import org.thoughtcrime.securesms.keyvalue.SignalStore;
|
||||
import org.thoughtcrime.securesms.util.TextSecurePreferences;
|
||||
import org.whispersystems.signalservice.api.SignalServiceDataStore;
|
||||
import org.whispersystems.signalservice.api.push.AccountIdentifier;
|
||||
import org.whispersystems.signalservice.api.push.ServiceId;
|
||||
|
||||
public final class SignalServiceDataStoreImpl implements SignalServiceDataStore {
|
||||
|
||||
|
@ -25,7 +25,7 @@ public final class SignalServiceDataStoreImpl implements SignalServiceDataStore
|
|||
}
|
||||
|
||||
@Override
|
||||
public SignalServiceAccountDataStoreImpl get(@NonNull AccountIdentifier accountIdentifier) {
|
||||
public SignalServiceAccountDataStoreImpl get(@NonNull ServiceId accountIdentifier) {
|
||||
if (accountIdentifier.equals(SignalStore.account().getAci())) {
|
||||
return aciStore;
|
||||
} else if (accountIdentifier.equals(SignalStore.account().getPni())) {
|
||||
|
|
|
@ -9,7 +9,7 @@ import org.whispersystems.libsignal.state.PreKeyRecord;
|
|||
import org.whispersystems.libsignal.state.PreKeyStore;
|
||||
import org.whispersystems.libsignal.state.SignedPreKeyRecord;
|
||||
import org.whispersystems.libsignal.state.SignedPreKeyStore;
|
||||
import org.whispersystems.signalservice.api.push.AccountIdentifier;
|
||||
import org.whispersystems.signalservice.api.push.ServiceId;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
|
@ -21,9 +21,9 @@ public class TextSecurePreKeyStore implements PreKeyStore, SignedPreKeyStore {
|
|||
private static final Object LOCK = new Object();
|
||||
|
||||
@NonNull
|
||||
private final AccountIdentifier accountId;
|
||||
private final ServiceId accountId;
|
||||
|
||||
public TextSecurePreKeyStore(@NonNull AccountIdentifier accountId) {
|
||||
public TextSecurePreKeyStore(@NonNull ServiceId accountId) {
|
||||
this.accountId = accountId;
|
||||
}
|
||||
|
||||
|
|
|
@ -1,7 +1,5 @@
|
|||
package org.thoughtcrime.securesms.crypto.storage;
|
||||
|
||||
import android.content.Context;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
|
||||
|
@ -15,7 +13,7 @@ import org.whispersystems.libsignal.SignalProtocolAddress;
|
|||
import org.whispersystems.libsignal.protocol.CiphertextMessage;
|
||||
import org.whispersystems.libsignal.state.SessionRecord;
|
||||
import org.whispersystems.signalservice.api.SignalServiceSessionStore;
|
||||
import org.whispersystems.signalservice.api.push.AccountIdentifier;
|
||||
import org.whispersystems.signalservice.api.push.ServiceId;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
|
@ -28,9 +26,9 @@ public class TextSecureSessionStore implements SignalServiceSessionStore {
|
|||
|
||||
private static final Object LOCK = new Object();
|
||||
|
||||
private final AccountIdentifier accountId;
|
||||
private final ServiceId accountId;
|
||||
|
||||
public TextSecureSessionStore(@NonNull AccountIdentifier accountId) {
|
||||
public TextSecureSessionStore(@NonNull ServiceId accountId) {
|
||||
this.accountId = accountId;
|
||||
}
|
||||
|
||||
|
@ -135,8 +133,8 @@ public class TextSecureSessionStore implements SignalServiceSessionStore {
|
|||
synchronized (LOCK) {
|
||||
Recipient recipient = Recipient.resolved(recipientId);
|
||||
|
||||
if (recipient.hasAci()) {
|
||||
archiveSession(new SignalProtocolAddress(recipient.requireAci().toString(), deviceId));
|
||||
if (recipient.hasServiceId()) {
|
||||
archiveSession(new SignalProtocolAddress(recipient.requireServiceId().toString(), deviceId));
|
||||
}
|
||||
|
||||
if (recipient.hasE164()) {
|
||||
|
|
|
@ -25,6 +25,7 @@ import org.thoughtcrime.securesms.crypto.SenderKeyUtil;
|
|||
import org.thoughtcrime.securesms.dependencies.ApplicationDependencies;
|
||||
import org.thoughtcrime.securesms.groups.v2.processing.GroupsV2StateProcessor;
|
||||
import org.thoughtcrime.securesms.jobs.RequestGroupV2InfoJob;
|
||||
import org.thoughtcrime.securesms.keyvalue.SignalStore;
|
||||
import org.whispersystems.signalservice.api.push.ACI;
|
||||
import org.whispersystems.signalservice.api.push.DistributionId;
|
||||
import org.thoughtcrime.securesms.groups.GroupAccessControl;
|
||||
|
@ -40,6 +41,7 @@ import org.whispersystems.libsignal.util.guava.Optional;
|
|||
import org.whispersystems.signalservice.api.groupsv2.DecryptedGroupUtil;
|
||||
import org.whispersystems.signalservice.api.groupsv2.GroupChangeReconstruct;
|
||||
import org.whispersystems.signalservice.api.messages.SignalServiceAttachmentPointer;
|
||||
import org.whispersystems.signalservice.api.push.ServiceId;
|
||||
import org.whispersystems.signalservice.api.util.UuidUtil;
|
||||
|
||||
import java.io.Closeable;
|
||||
|
@ -821,7 +823,7 @@ private static final String[] GROUP_PROJECTION = {
|
|||
}
|
||||
|
||||
private static boolean gv2GroupActive(@NonNull DecryptedGroup decryptedGroup) {
|
||||
ACI aci = Recipient.self().requireAci();
|
||||
ACI aci = SignalStore.account().requireAci();
|
||||
|
||||
return DecryptedGroupUtil.findMemberByUuid(decryptedGroup.getMembersList(), aci.uuid()).isPresent() ||
|
||||
DecryptedGroupUtil.findPendingByUuid(decryptedGroup.getPendingMembersList(), aci.uuid()).isPresent();
|
||||
|
@ -1232,9 +1234,9 @@ private static final String[] GROUP_PROJECTION = {
|
|||
*/
|
||||
public boolean isPendingMember(@NonNull Recipient recipient) {
|
||||
if (isV2Group()) {
|
||||
Optional<ACI> aci = recipient.getAci();
|
||||
if (aci.isPresent()) {
|
||||
return DecryptedGroupUtil.findPendingByUuid(requireV2GroupProperties().getDecryptedGroup().getPendingMembersList(), aci.get().uuid())
|
||||
Optional<ServiceId> serviceId = recipient.getServiceId();
|
||||
if (serviceId.isPresent()) {
|
||||
return DecryptedGroupUtil.findPendingByUuid(requireV2GroupProperties().getDecryptedGroup().getPendingMembersList(), serviceId.get().uuid())
|
||||
.isPresent();
|
||||
}
|
||||
}
|
||||
|
@ -1275,13 +1277,13 @@ private static final String[] GROUP_PROJECTION = {
|
|||
}
|
||||
|
||||
public boolean isAdmin(@NonNull Recipient recipient) {
|
||||
Optional<ACI> aci = recipient.getAci();
|
||||
Optional<ServiceId> serviceId = recipient.getServiceId();
|
||||
|
||||
if (!aci.isPresent()) {
|
||||
if (!serviceId.isPresent()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return DecryptedGroupUtil.findMemberByUuid(getDecryptedGroup().getMembersList(), aci.get().uuid())
|
||||
return DecryptedGroupUtil.findMemberByUuid(getDecryptedGroup().getMembersList(), serviceId.get().uuid())
|
||||
.transform(t -> t.getRole() == Member.Role.ADMINISTRATOR)
|
||||
.or(false);
|
||||
}
|
||||
|
@ -1291,21 +1293,21 @@ private static final String[] GROUP_PROJECTION = {
|
|||
}
|
||||
|
||||
public MemberLevel memberLevel(@NonNull Recipient recipient) {
|
||||
Optional<ACI> aci = recipient.getAci();
|
||||
Optional<ServiceId> serviceId = recipient.getServiceId();
|
||||
|
||||
if (!aci.isPresent()) {
|
||||
if (!serviceId.isPresent()) {
|
||||
return MemberLevel.NOT_A_MEMBER;
|
||||
}
|
||||
|
||||
DecryptedGroup decryptedGroup = getDecryptedGroup();
|
||||
|
||||
return DecryptedGroupUtil.findMemberByUuid(decryptedGroup.getMembersList(), aci.get().uuid())
|
||||
return DecryptedGroupUtil.findMemberByUuid(decryptedGroup.getMembersList(), serviceId.get().uuid())
|
||||
.transform(member -> member.getRole() == Member.Role.ADMINISTRATOR
|
||||
? MemberLevel.ADMINISTRATOR
|
||||
: MemberLevel.FULL_MEMBER)
|
||||
.or(() -> DecryptedGroupUtil.findPendingByUuid(decryptedGroup.getPendingMembersList(), aci.get().uuid())
|
||||
.or(() -> DecryptedGroupUtil.findPendingByUuid(decryptedGroup.getPendingMembersList(), serviceId.get().uuid())
|
||||
.transform(m -> MemberLevel.PENDING_MEMBER)
|
||||
.or(() -> DecryptedGroupUtil.findRequestingByUuid(decryptedGroup.getRequestingMembersList(), aci.get().uuid())
|
||||
.or(() -> DecryptedGroupUtil.findRequestingByUuid(decryptedGroup.getRequestingMembersList(), serviceId.get().uuid())
|
||||
.transform(m -> MemberLevel.REQUESTING_MEMBER)
|
||||
.or(MemberLevel.NOT_A_MEMBER)));
|
||||
}
|
||||
|
@ -1317,7 +1319,7 @@ private static final String[] GROUP_PROJECTION = {
|
|||
public List<RecipientId> getMemberRecipientIds(@NonNull MemberSet memberSet) {
|
||||
boolean includeSelf = memberSet.includeSelf;
|
||||
DecryptedGroup groupV2 = getDecryptedGroup();
|
||||
UUID selfUuid = Recipient.self().requireAci().uuid();
|
||||
UUID selfUuid = Recipient.self().requireServiceId().uuid();
|
||||
List<RecipientId> recipients = new ArrayList<>(groupV2.getMembersCount() + groupV2.getPendingMembersCount());
|
||||
int unknownMembers = 0;
|
||||
int unknownPending = 0;
|
||||
|
|
|
@ -19,7 +19,6 @@ 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;
|
||||
import java.util.Collections;
|
||||
|
@ -106,7 +105,7 @@ public final class MentionUtil {
|
|||
BodyRangeList.Builder builder = BodyRangeList.newBuilder();
|
||||
|
||||
for (Mention mention : mentions) {
|
||||
String uuid = Recipient.resolved(mention.getRecipientId()).requireAci().toString();
|
||||
String uuid = Recipient.resolved(mention.getRecipientId()).requireServiceId().toString();
|
||||
builder.addRanges(BodyRangeList.BodyRange.newBuilder()
|
||||
.setMentionUuid(uuid)
|
||||
.setStart(mention.getStart())
|
||||
|
@ -122,7 +121,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, ACI.parseOrThrow(mention.getMentionUuid()), null, false).getId();
|
||||
RecipientId id = Recipient.externalPush(ACI.parseOrThrow(mention.getMentionUuid()), null, false).getId();
|
||||
return new Mention(id, mention.getStart(), mention.getLength());
|
||||
})
|
||||
.toList();
|
||||
|
|
|
@ -9,7 +9,7 @@ import org.whispersystems.libsignal.InvalidKeyException
|
|||
import org.whispersystems.libsignal.ecc.Curve
|
||||
import org.whispersystems.libsignal.ecc.ECKeyPair
|
||||
import org.whispersystems.libsignal.state.PreKeyRecord
|
||||
import org.whispersystems.signalservice.api.push.AccountIdentifier
|
||||
import org.whispersystems.signalservice.api.push.ServiceId
|
||||
import java.io.IOException
|
||||
|
||||
class OneTimePreKeyDatabase(context: Context, databaseHelper: SignalDatabase) : Database(context, databaseHelper) {
|
||||
|
@ -34,8 +34,8 @@ class OneTimePreKeyDatabase(context: Context, databaseHelper: SignalDatabase) :
|
|||
"""
|
||||
}
|
||||
|
||||
fun get(accountId: AccountIdentifier, keyId: Int): PreKeyRecord? {
|
||||
readableDatabase.query(TABLE_NAME, null, "$ACCOUNT_ID = ? AND $KEY_ID = ?", SqlUtil.buildArgs(accountId, keyId), null, null, null).use { cursor ->
|
||||
fun get(serviceId: ServiceId, keyId: Int): PreKeyRecord? {
|
||||
readableDatabase.query(TABLE_NAME, null, "$ACCOUNT_ID = ? AND $KEY_ID = ?", SqlUtil.buildArgs(serviceId, keyId), null, null, null).use { cursor ->
|
||||
if (cursor.moveToFirst()) {
|
||||
try {
|
||||
val publicKey = Curve.decodePoint(Base64.decode(cursor.requireNonNullString(PUBLIC_KEY)), 0)
|
||||
|
@ -52,9 +52,9 @@ class OneTimePreKeyDatabase(context: Context, databaseHelper: SignalDatabase) :
|
|||
return null
|
||||
}
|
||||
|
||||
fun insert(accountId: AccountIdentifier, keyId: Int, record: PreKeyRecord) {
|
||||
fun insert(serviceId: ServiceId, keyId: Int, record: PreKeyRecord) {
|
||||
val contentValues = contentValuesOf(
|
||||
ACCOUNT_ID to accountId.toString(),
|
||||
ACCOUNT_ID to serviceId.toString(),
|
||||
KEY_ID to keyId,
|
||||
PUBLIC_KEY to Base64.encodeBytes(record.keyPair.publicKey.serialize()),
|
||||
PRIVATE_KEY to Base64.encodeBytes(record.keyPair.privateKey.serialize())
|
||||
|
@ -63,8 +63,8 @@ class OneTimePreKeyDatabase(context: Context, databaseHelper: SignalDatabase) :
|
|||
writableDatabase.replace(TABLE_NAME, null, contentValues)
|
||||
}
|
||||
|
||||
fun delete(accountId: AccountIdentifier, keyId: Int) {
|
||||
fun delete(serviceId: ServiceId, keyId: Int) {
|
||||
val database = databaseHelper.signalWritableDatabase
|
||||
database.delete(TABLE_NAME, "$ACCOUNT_ID = ? AND $KEY_ID = ?", SqlUtil.buildArgs(accountId, keyId))
|
||||
database.delete(TABLE_NAME, "$ACCOUNT_ID = ? AND $KEY_ID = ?", SqlUtil.buildArgs(serviceId, keyId))
|
||||
}
|
||||
}
|
||||
|
|
|
@ -79,6 +79,7 @@ import org.whispersystems.libsignal.util.guava.Optional
|
|||
import org.whispersystems.signalservice.api.profiles.SignalServiceProfile
|
||||
import org.whispersystems.signalservice.api.push.ACI
|
||||
import org.whispersystems.signalservice.api.push.PNI
|
||||
import org.whispersystems.signalservice.api.push.ServiceId
|
||||
import org.whispersystems.signalservice.api.push.SignalServiceAddress
|
||||
import org.whispersystems.signalservice.api.storage.SignalAccountRecord
|
||||
import org.whispersystems.signalservice.api.storage.SignalContactRecord
|
||||
|
@ -110,7 +111,7 @@ open class RecipientDatabase(context: Context, databaseHelper: SignalDatabase) :
|
|||
const val TABLE_NAME = "recipient"
|
||||
|
||||
const val ID = "_id"
|
||||
private const val ACI_COLUMN = "uuid"
|
||||
private const val SERVICE_ID = "uuid"
|
||||
private const val PNI_COLUMN = "pni"
|
||||
private const val USERNAME = "username"
|
||||
const val PHONE = "phone"
|
||||
|
@ -171,7 +172,7 @@ open class RecipientDatabase(context: Context, databaseHelper: SignalDatabase) :
|
|||
"""
|
||||
CREATE TABLE $TABLE_NAME (
|
||||
$ID INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||
$ACI_COLUMN TEXT UNIQUE DEFAULT NULL,
|
||||
$SERVICE_ID TEXT UNIQUE DEFAULT NULL,
|
||||
$USERNAME TEXT UNIQUE DEFAULT NULL,
|
||||
$PHONE TEXT UNIQUE DEFAULT NULL,
|
||||
$EMAIL TEXT UNIQUE DEFAULT NULL,
|
||||
|
@ -232,7 +233,7 @@ open class RecipientDatabase(context: Context, databaseHelper: SignalDatabase) :
|
|||
|
||||
private val RECIPIENT_PROJECTION: Array<String> = arrayOf(
|
||||
ID,
|
||||
ACI_COLUMN,
|
||||
SERVICE_ID,
|
||||
PNI_COLUMN,
|
||||
USERNAME,
|
||||
PHONE,
|
||||
|
@ -367,7 +368,7 @@ open class RecipientDatabase(context: Context, databaseHelper: SignalDatabase) :
|
|||
}
|
||||
|
||||
fun containsPhoneOrUuid(id: String): Boolean {
|
||||
val query = "$ACI_COLUMN = ? OR $PHONE = ?"
|
||||
val query = "$SERVICE_ID = ? OR $PHONE = ?"
|
||||
val args = arrayOf(id, id)
|
||||
readableDatabase.query(TABLE_NAME, arrayOf(ID), query, args, null, null, null).use { cursor -> return cursor != null && cursor.moveToFirst() }
|
||||
}
|
||||
|
@ -384,20 +385,20 @@ open class RecipientDatabase(context: Context, databaseHelper: SignalDatabase) :
|
|||
return getByColumn(GROUP_ID, groupId.toString())
|
||||
}
|
||||
|
||||
fun getByAci(uuid: ACI): Optional<RecipientId> {
|
||||
return getByColumn(ACI_COLUMN, uuid.toString())
|
||||
fun getByServiceId(serviceId: ServiceId): Optional<RecipientId> {
|
||||
return getByColumn(SERVICE_ID, serviceId.toString())
|
||||
}
|
||||
|
||||
fun getByUsername(username: String): Optional<RecipientId> {
|
||||
return getByColumn(USERNAME, username)
|
||||
}
|
||||
|
||||
fun getAndPossiblyMerge(aci: ACI?, e164: String?, highTrust: Boolean): RecipientId {
|
||||
return getAndPossiblyMerge(aci, e164, highTrust, false)
|
||||
fun getAndPossiblyMerge(serviceId: ServiceId?, e164: String?, highTrust: Boolean): RecipientId {
|
||||
return getAndPossiblyMerge(serviceId, e164, highTrust, false)
|
||||
}
|
||||
|
||||
fun getAndPossiblyMerge(aci: ACI?, e164: String?, highTrust: Boolean, changeSelf: Boolean): RecipientId {
|
||||
require(!(aci == null && e164 == null)) { "Must provide an ACI or E164!" }
|
||||
fun getAndPossiblyMerge(serviceId: ServiceId?, e164: String?, highTrust: Boolean, changeSelf: Boolean): RecipientId {
|
||||
require(!(serviceId == null && e164 == null)) { "Must provide an ACI or E164!" }
|
||||
|
||||
val db = writableDatabase
|
||||
|
||||
|
@ -408,7 +409,7 @@ open class RecipientDatabase(context: Context, databaseHelper: SignalDatabase) :
|
|||
|
||||
db.beginTransaction()
|
||||
try {
|
||||
val fetch: RecipientFetch = fetchRecipient(aci, e164, highTrust, changeSelf)
|
||||
val fetch: RecipientFetch = fetchRecipient(serviceId, e164, highTrust, changeSelf)
|
||||
|
||||
if (fetch.logBundle != null) {
|
||||
Log.w(TAG, fetch.toString())
|
||||
|
@ -432,29 +433,29 @@ open class RecipientDatabase(context: Context, databaseHelper: SignalDatabase) :
|
|||
fetch.id
|
||||
}
|
||||
is RecipientFetch.MatchAndUpdateAci -> {
|
||||
markRegistered(fetch.id, fetch.aci)
|
||||
markRegistered(fetch.id, fetch.serviceId)
|
||||
recipientsNeedingRefresh = listOf(fetch.id)
|
||||
fetch.id
|
||||
}
|
||||
is RecipientFetch.MatchAndInsertAci -> {
|
||||
val id = db.insert(TABLE_NAME, null, buildContentValuesForNewUser(null, fetch.aci))
|
||||
val id = db.insert(TABLE_NAME, null, buildContentValuesForNewUser(null, fetch.serviceId))
|
||||
RecipientId.from(id)
|
||||
}
|
||||
is RecipientFetch.MatchAndMerge -> {
|
||||
remapped = Pair(fetch.e164Id, fetch.aciId)
|
||||
val mergedId: RecipientId = merge(fetch.aciId, fetch.e164Id)
|
||||
remapped = Pair(fetch.e164Id, fetch.sidId)
|
||||
val mergedId: RecipientId = merge(fetch.sidId, fetch.e164Id)
|
||||
recipientsNeedingRefresh = listOf(mergedId)
|
||||
recipientChangedNumber = fetch.changedNumber
|
||||
mergedId
|
||||
}
|
||||
is RecipientFetch.Insert -> {
|
||||
val id = db.insert(TABLE_NAME, null, buildContentValuesForNewUser(fetch.e164, fetch.aci))
|
||||
val id = db.insert(TABLE_NAME, null, buildContentValuesForNewUser(fetch.e164, fetch.serviceId))
|
||||
RecipientId.from(id)
|
||||
}
|
||||
is RecipientFetch.InsertAndReassignE164 -> {
|
||||
removePhoneNumber(fetch.e164Id, db)
|
||||
recipientsNeedingRefresh = listOf(fetch.e164Id)
|
||||
val id = db.insert(TABLE_NAME, null, buildContentValuesForNewUser(fetch.e164, fetch.aci))
|
||||
val id = db.insert(TABLE_NAME, null, buildContentValuesForNewUser(fetch.e164, fetch.serviceId))
|
||||
RecipientId.from(id)
|
||||
}
|
||||
}
|
||||
|
@ -488,12 +489,12 @@ open class RecipientDatabase(context: Context, databaseHelper: SignalDatabase) :
|
|||
}
|
||||
}
|
||||
|
||||
private fun fetchRecipient(aci: ACI?, e164: String?, highTrust: Boolean, changeSelf: Boolean): RecipientFetch {
|
||||
private fun fetchRecipient(serviceId: ServiceId?, e164: String?, highTrust: Boolean, changeSelf: Boolean): RecipientFetch {
|
||||
val byE164 = e164?.let { getByE164(it) } ?: Optional.absent()
|
||||
val byAci = aci?.let { getByAci(it) } ?: Optional.absent()
|
||||
val byAci = serviceId?.let { getByServiceId(it) } ?: Optional.absent()
|
||||
|
||||
var logs = LogBundle(
|
||||
byAci = byAci.transform { id -> RecipientLogDetails(id = id) }.orNull(),
|
||||
bySid = byAci.transform { id -> RecipientLogDetails(id = id) }.orNull(),
|
||||
byE164 = byE164.transform { id -> RecipientLogDetails(id = id) }.orNull(),
|
||||
label = "L0"
|
||||
)
|
||||
|
@ -504,9 +505,9 @@ open class RecipientDatabase(context: Context, databaseHelper: SignalDatabase) :
|
|||
|
||||
if (byAci.isPresent && byE164.isAbsent()) {
|
||||
val aciRecord: RecipientRecord = getRecord(byAci.get())
|
||||
logs = logs.copy(byAci = aciRecord.toLogDetails())
|
||||
logs = logs.copy(bySid = aciRecord.toLogDetails())
|
||||
|
||||
if (highTrust && e164 != null && (changeSelf || aci != SignalStore.account().aci)) {
|
||||
if (highTrust && e164 != null && (changeSelf || serviceId != SignalStore.account().aci)) {
|
||||
val changedNumber: RecipientId? = if (aciRecord.e164 != null && aciRecord.e164 != e164) aciRecord.id else null
|
||||
return RecipientFetch.MatchAndUpdateE164(byAci.get(), e164, changedNumber, logs.label("L1"))
|
||||
} else if (e164 == null) {
|
||||
|
@ -520,12 +521,12 @@ open class RecipientDatabase(context: Context, databaseHelper: SignalDatabase) :
|
|||
val e164Record: RecipientRecord = getRecord(byE164.get())
|
||||
logs = logs.copy(byE164 = e164Record.toLogDetails())
|
||||
|
||||
if (highTrust && aci != null && e164Record.aci == null) {
|
||||
return RecipientFetch.MatchAndUpdateAci(byE164.get(), aci, logs.label("L3"))
|
||||
} else if (highTrust && aci != null && e164Record.aci != SignalStore.account().aci) {
|
||||
return RecipientFetch.InsertAndReassignE164(aci, e164, byE164.get(), logs.label("L4"))
|
||||
} else if (aci != null) {
|
||||
return RecipientFetch.Insert(aci, null, logs.label("L5"))
|
||||
if (highTrust && serviceId != null && e164Record.serviceId == null) {
|
||||
return RecipientFetch.MatchAndUpdateAci(byE164.get(), serviceId, logs.label("L3"))
|
||||
} else if (highTrust && serviceId != null && e164Record.serviceId != SignalStore.account().aci) {
|
||||
return RecipientFetch.InsertAndReassignE164(serviceId, e164, byE164.get(), logs.label("L4"))
|
||||
} else if (serviceId != null) {
|
||||
return RecipientFetch.Insert(serviceId, null, logs.label("L5"))
|
||||
} else {
|
||||
return RecipientFetch.Match(byE164.get(), null)
|
||||
}
|
||||
|
@ -533,9 +534,9 @@ open class RecipientDatabase(context: Context, databaseHelper: SignalDatabase) :
|
|||
|
||||
if (byAci.isAbsent() && byE164.isAbsent()) {
|
||||
if (highTrust) {
|
||||
return RecipientFetch.Insert(aci, e164, logs.label("L6"))
|
||||
} else if (aci != null) {
|
||||
return RecipientFetch.Insert(aci, null, logs.label("L7"))
|
||||
return RecipientFetch.Insert(serviceId, e164, logs.label("L6"))
|
||||
} else if (serviceId != null) {
|
||||
return RecipientFetch.Insert(serviceId, null, logs.label("L7"))
|
||||
} else {
|
||||
return RecipientFetch.Insert(null, e164, logs.label("L8"))
|
||||
}
|
||||
|
@ -546,17 +547,17 @@ open class RecipientDatabase(context: Context, databaseHelper: SignalDatabase) :
|
|||
val aciRecord: RecipientRecord = getRecord(byAci.get())
|
||||
val e164Record: RecipientRecord = getRecord(byE164.get())
|
||||
|
||||
logs = logs.copy(byAci = aciRecord.toLogDetails(), byE164 = e164Record.toLogDetails())
|
||||
logs = logs.copy(bySid = aciRecord.toLogDetails(), byE164 = e164Record.toLogDetails())
|
||||
|
||||
if (e164Record.aci == null) {
|
||||
if (e164Record.serviceId == null) {
|
||||
if (highTrust) {
|
||||
val changedNumber: RecipientId? = if (aciRecord.e164 != null) aciRecord.id else null
|
||||
return RecipientFetch.MatchAndMerge(aciId = byAci.get(), e164Id = byE164.get(), changedNumber = changedNumber, logs.label("L9"))
|
||||
return RecipientFetch.MatchAndMerge(sidId = byAci.get(), e164Id = byE164.get(), changedNumber = changedNumber, logs.label("L9"))
|
||||
} else {
|
||||
return RecipientFetch.Match(byAci.get(), logs.label("L10"))
|
||||
}
|
||||
} else {
|
||||
if (highTrust && e164Record.aci != SignalStore.account().aci) {
|
||||
if (highTrust && e164Record.serviceId != SignalStore.account().aci) {
|
||||
val changedNumber: RecipientId? = if (aciRecord.e164 != null) aciRecord.id else null
|
||||
return RecipientFetch.MatchAndReassignE164(id = byAci.get(), e164Id = byE164.get(), e164 = e164!!, changedNumber = changedNumber, logs.label("L11"))
|
||||
} else {
|
||||
|
@ -565,8 +566,8 @@ open class RecipientDatabase(context: Context, databaseHelper: SignalDatabase) :
|
|||
}
|
||||
}
|
||||
|
||||
fun getOrInsertFromAci(aci: ACI): RecipientId {
|
||||
return getOrInsertByColumn(ACI_COLUMN, aci.toString()).recipientId
|
||||
fun getOrInsertFromServiceId(serviceId: ServiceId): RecipientId {
|
||||
return getOrInsertByColumn(SERVICE_ID, serviceId.toString()).recipientId
|
||||
}
|
||||
|
||||
fun getOrInsertFromE164(e164: String): RecipientId {
|
||||
|
@ -785,13 +786,13 @@ open class RecipientDatabase(context: Context, databaseHelper: SignalDatabase) :
|
|||
val recipientId: RecipientId?
|
||||
if (id < 0) {
|
||||
Log.w(TAG, "[applyStorageSyncContactInsert] Failed to insert. Possibly merging.")
|
||||
recipientId = getAndPossiblyMerge(if (insert.address.hasValidAci()) insert.address.aci else null, insert.address.number.orNull(), true)
|
||||
recipientId = getAndPossiblyMerge(if (insert.address.hasValidServiceId()) insert.address.serviceId else null, insert.address.number.orNull(), true)
|
||||
db.update(TABLE_NAME, values, ID_WHERE, SqlUtil.buildArgs(recipientId))
|
||||
} else {
|
||||
recipientId = RecipientId.from(id)
|
||||
}
|
||||
|
||||
if (insert.identityKey.isPresent && insert.address.hasValidAci()) {
|
||||
if (insert.identityKey.isPresent && insert.address.hasValidServiceId()) {
|
||||
try {
|
||||
val identityKey = IdentityKey(insert.identityKey.get(), 0)
|
||||
identities.updateIdentityAfterSync(insert.address.identifier, recipientId!!, identityKey, StorageSyncModels.remoteToLocalIdentityStatus(insert.identityState))
|
||||
|
@ -818,7 +819,7 @@ open class RecipientDatabase(context: Context, databaseHelper: SignalDatabase) :
|
|||
var recipientId = getByColumn(STORAGE_SERVICE_ID, Base64.encodeBytes(update.old.id.raw)).get()
|
||||
|
||||
Log.w(TAG, "[applyStorageSyncContactUpdate] Found user $recipientId. Possibly merging.")
|
||||
recipientId = getAndPossiblyMerge(if (update.new.address.hasValidAci()) update.new.address.aci else null, update.new.address.number.orNull(), true)
|
||||
recipientId = getAndPossiblyMerge(if (update.new.address.hasValidServiceId()) update.new.address.serviceId else null, update.new.address.number.orNull(), true)
|
||||
|
||||
Log.w(TAG, "[applyStorageSyncContactUpdate] Merged into $recipientId")
|
||||
db.update(TABLE_NAME, values, ID_WHERE, SqlUtil.buildArgs(recipientId))
|
||||
|
@ -834,7 +835,7 @@ open class RecipientDatabase(context: Context, databaseHelper: SignalDatabase) :
|
|||
|
||||
try {
|
||||
val oldIdentityRecord = identityStore.getIdentityRecord(recipientId)
|
||||
if (update.new.identityKey.isPresent && update.new.address.hasValidAci()) {
|
||||
if (update.new.identityKey.isPresent && update.new.address.hasValidServiceId()) {
|
||||
val identityKey = IdentityKey(update.new.identityKey.get(), 0)
|
||||
identities.updateIdentityAfterSync(update.new.address.identifier, recipientId, identityKey, StorageSyncModels.remoteToLocalIdentityStatus(update.new.identityState))
|
||||
}
|
||||
|
@ -982,7 +983,7 @@ open class RecipientDatabase(context: Context, databaseHelper: SignalDatabase) :
|
|||
private fun getRecordForSync(query: String?, args: Array<String>?): List<RecipientRecord> {
|
||||
val table =
|
||||
"""
|
||||
$TABLE_NAME LEFT OUTER JOIN ${IdentityDatabase.TABLE_NAME} ON $TABLE_NAME.$ACI_COLUMN = ${IdentityDatabase.TABLE_NAME}.${IdentityDatabase.ADDRESS}
|
||||
$TABLE_NAME LEFT OUTER JOIN ${IdentityDatabase.TABLE_NAME} ON $TABLE_NAME.$SERVICE_ID = ${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}
|
||||
""".trimIndent()
|
||||
|
@ -1018,7 +1019,7 @@ open class RecipientDatabase(context: Context, databaseHelper: SignalDatabase) :
|
|||
fun getContactStorageSyncIdsMap(): Map<RecipientId, StorageId> {
|
||||
val query = """
|
||||
$STORAGE_SERVICE_ID NOT NULL AND (
|
||||
($GROUP_TYPE = ? AND $ACI_COLUMN NOT NULL AND $ID != ?)
|
||||
($GROUP_TYPE = ? AND $SERVICE_ID NOT NULL AND $ID != ?)
|
||||
OR
|
||||
$GROUP_TYPE IN (?)
|
||||
)
|
||||
|
@ -1505,7 +1506,7 @@ open class RecipientDatabase(context: Context, databaseHelper: SignalDatabase) :
|
|||
val selfId = Recipient.self().id
|
||||
|
||||
for ((key, value) in profileKeys) {
|
||||
val recipientId = getOrInsertFromAci(key)
|
||||
val recipientId = getOrInsertFromServiceId(key)
|
||||
if (setProfileKeyIfAbsent(recipientId, value)) {
|
||||
Log.i(TAG, "Learned new profile key")
|
||||
updated.add(recipientId)
|
||||
|
@ -1513,7 +1514,7 @@ open class RecipientDatabase(context: Context, databaseHelper: SignalDatabase) :
|
|||
}
|
||||
|
||||
for ((key, value) in authoritativeProfileKeys) {
|
||||
val recipientId = getOrInsertFromAci(key)
|
||||
val recipientId = getOrInsertFromServiceId(key)
|
||||
|
||||
if (selfId == recipientId) {
|
||||
Log.i(TAG, "Seen authoritative update for self")
|
||||
|
@ -1760,7 +1761,7 @@ open class RecipientDatabase(context: Context, databaseHelper: SignalDatabase) :
|
|||
Log.w(TAG, "[setPhoneNumber] Hit a conflict when trying to update $id. Possibly merging.")
|
||||
|
||||
val existing: RecipientRecord = getRecord(id)
|
||||
val newId = getAndPossiblyMerge(existing.aci, e164, true)
|
||||
val newId = getAndPossiblyMerge(existing.serviceId, e164, true)
|
||||
Log.w(TAG, "[setPhoneNumber] Resulting id: $newId")
|
||||
|
||||
db.setTransactionSuccessful()
|
||||
|
@ -1812,7 +1813,7 @@ open class RecipientDatabase(context: Context, databaseHelper: SignalDatabase) :
|
|||
db.beginTransaction()
|
||||
try {
|
||||
val id = Recipient.self().id
|
||||
val newId = getAndPossiblyMerge(Recipient.self().requireAci(), e164, highTrust = true, changeSelf = true)
|
||||
val newId = getAndPossiblyMerge(Recipient.self().requireServiceId(), e164, highTrust = true, changeSelf = true)
|
||||
|
||||
if (id == newId) {
|
||||
Log.i(TAG, "[updateSelfPhone] Phone updated for self")
|
||||
|
@ -1874,19 +1875,19 @@ open class RecipientDatabase(context: Context, databaseHelper: SignalDatabase) :
|
|||
/**
|
||||
* @return True if setting the UUID resulted in changed recipientId, otherwise false.
|
||||
*/
|
||||
fun markRegistered(id: RecipientId, aci: ACI): Boolean {
|
||||
fun markRegistered(id: RecipientId, serviceId: ServiceId): Boolean {
|
||||
val db = writableDatabase
|
||||
|
||||
db.beginTransaction()
|
||||
try {
|
||||
markRegisteredOrThrow(id, aci)
|
||||
markRegisteredOrThrow(id, serviceId)
|
||||
db.setTransactionSuccessful()
|
||||
return false
|
||||
} catch (e: SQLiteConstraintException) {
|
||||
Log.w(TAG, "[markRegistered] Hit a conflict when trying to update $id. Possibly merging.")
|
||||
|
||||
val existing = getRecord(id)
|
||||
val newId = getAndPossiblyMerge(aci, existing.e164, true)
|
||||
val newId = getAndPossiblyMerge(serviceId, existing.e164, true)
|
||||
Log.w(TAG, "[markRegistered] Merged into $newId")
|
||||
|
||||
db.setTransactionSuccessful()
|
||||
|
@ -1899,10 +1900,10 @@ open class RecipientDatabase(context: Context, databaseHelper: SignalDatabase) :
|
|||
/**
|
||||
* Should only use if you are confident that this shouldn't result in any contact merging.
|
||||
*/
|
||||
fun markRegisteredOrThrow(id: RecipientId, aci: ACI) {
|
||||
fun markRegisteredOrThrow(id: RecipientId, serviceId: ServiceId) {
|
||||
val contentValues = ContentValues(2).apply {
|
||||
put(REGISTERED, RegisteredState.REGISTERED.id)
|
||||
put(ACI_COLUMN, aci.toString().toLowerCase())
|
||||
put(SERVICE_ID, serviceId.toString().toLowerCase())
|
||||
}
|
||||
if (update(id, contentValues)) {
|
||||
setStorageIdIfNotSet(id)
|
||||
|
@ -1920,7 +1921,7 @@ open class RecipientDatabase(context: Context, databaseHelper: SignalDatabase) :
|
|||
}
|
||||
}
|
||||
|
||||
fun bulkUpdatedRegisteredStatus(registered: Map<RecipientId, ACI?>, unregistered: Collection<RecipientId>) {
|
||||
fun bulkUpdatedRegisteredStatus(registered: Map<RecipientId, ServiceId?>, unregistered: Collection<RecipientId>) {
|
||||
val db = writableDatabase
|
||||
|
||||
db.beginTransaction()
|
||||
|
@ -1929,7 +1930,7 @@ open class RecipientDatabase(context: Context, databaseHelper: SignalDatabase) :
|
|||
val values = ContentValues(2).apply {
|
||||
put(REGISTERED, RegisteredState.REGISTERED.id)
|
||||
if (aci != null) {
|
||||
put(ACI_COLUMN, aci.toString().toLowerCase())
|
||||
put(SERVICE_ID, aci.toString().toLowerCase())
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1972,12 +1973,12 @@ open class RecipientDatabase(context: Context, databaseHelper: SignalDatabase) :
|
|||
db.beginTransaction()
|
||||
try {
|
||||
for ((e164, aci) in mapping) {
|
||||
var aciEntry = if (aci != null) getByAci(aci) else Optional.absent()
|
||||
var aciEntry = if (aci != null) getByServiceId(aci) else Optional.absent()
|
||||
|
||||
if (aciEntry.isPresent) {
|
||||
val idChanged = setPhoneNumber(aciEntry.get(), e164)
|
||||
if (idChanged) {
|
||||
aciEntry = getByAci(aci!!)
|
||||
aciEntry = getByServiceId(aci!!)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -2272,7 +2273,7 @@ open class RecipientDatabase(context: Context, databaseHelper: SignalDatabase) :
|
|||
.toList()
|
||||
|
||||
val blockedUuid = blocked
|
||||
.map { b: SignalServiceAddress -> b.aci.toString().toLowerCase() }
|
||||
.map { b: SignalServiceAddress -> b.serviceId.toString().toLowerCase() }
|
||||
.toList()
|
||||
|
||||
val db = writableDatabase
|
||||
|
@ -2293,7 +2294,7 @@ open class RecipientDatabase(context: Context, databaseHelper: SignalDatabase) :
|
|||
}
|
||||
|
||||
for (uuid in blockedUuid) {
|
||||
db.update(TABLE_NAME, setBlocked, "$ACI_COLUMN = ?", arrayOf(uuid))
|
||||
db.update(TABLE_NAME, setBlocked, "$SERVICE_ID = ?", arrayOf(uuid))
|
||||
}
|
||||
|
||||
val groupIdStrings: MutableList<V1> = ArrayList(groupIds.size)
|
||||
|
@ -2604,10 +2605,10 @@ open class RecipientDatabase(context: Context, databaseHelper: SignalDatabase) :
|
|||
}
|
||||
|
||||
// Sessions
|
||||
val localAci: ACI = SignalStore.account().aci!!
|
||||
val localAci: ACI = SignalStore.account().requireAci()
|
||||
val sessionDatabase = sessions
|
||||
val hasE164Session = sessionDatabase.getAllFor(localAci, e164Record.e164).isNotEmpty()
|
||||
val hasAciSession = sessionDatabase.getAllFor(localAci, aciRecord.aci.toString()).isNotEmpty()
|
||||
val hasAciSession = sessionDatabase.getAllFor(localAci, aciRecord.serviceId.toString()).isNotEmpty()
|
||||
|
||||
if (hasE164Session && hasAciSession) {
|
||||
Log.w(TAG, "Had a session for both users. Deleting the E164.", true)
|
||||
|
@ -2615,7 +2616,7 @@ open class RecipientDatabase(context: Context, databaseHelper: SignalDatabase) :
|
|||
} else if (hasE164Session && !hasAciSession) {
|
||||
Log.w(TAG, "Had a session for E164, but not ACI. Re-assigning to the ACI.", true)
|
||||
val values = ContentValues().apply {
|
||||
put(SessionDatabase.ADDRESS, aciRecord.aci.toString())
|
||||
put(SessionDatabase.ADDRESS, aciRecord.serviceId.toString())
|
||||
}
|
||||
db.update(SessionDatabase.TABLE_NAME, values, "${SessionDatabase.ACCOUNT_ID} = ? AND ${SessionDatabase.ADDRESS} = ?", SqlUtil.buildArgs(localAci, e164Record.e164))
|
||||
} else if (!hasE164Session && hasAciSession) {
|
||||
|
@ -2694,11 +2695,11 @@ open class RecipientDatabase(context: Context, databaseHelper: SignalDatabase) :
|
|||
check(writableDatabase.inTransaction()) { "Must be in a transaction!" }
|
||||
}
|
||||
|
||||
private fun buildContentValuesForNewUser(e164: String?, aci: ACI?): ContentValues {
|
||||
private fun buildContentValuesForNewUser(e164: String?, serviceId: ServiceId?): ContentValues {
|
||||
val values = ContentValues()
|
||||
values.put(PHONE, e164)
|
||||
if (aci != null) {
|
||||
values.put(ACI_COLUMN, aci.toString().toLowerCase())
|
||||
if (serviceId != null) {
|
||||
values.put(SERVICE_ID, serviceId.toString().toLowerCase())
|
||||
values.put(REGISTERED, RegisteredState.REGISTERED.id)
|
||||
values.put(STORAGE_SERVICE_ID, Base64.encodeBytes(StorageSyncHelper.generateKey()))
|
||||
values.put(AVATAR_COLOR, AvatarColor.random().serialize())
|
||||
|
@ -2711,8 +2712,8 @@ open class RecipientDatabase(context: Context, databaseHelper: SignalDatabase) :
|
|||
val profileName = ProfileName.fromParts(contact.givenName.orNull(), contact.familyName.orNull())
|
||||
val username = contact.username.orNull()
|
||||
|
||||
if (contact.address.hasValidAci()) {
|
||||
put(ACI_COLUMN, contact.address.aci.toString())
|
||||
if (contact.address.hasValidServiceId()) {
|
||||
put(SERVICE_ID, contact.address.serviceId.toString())
|
||||
}
|
||||
|
||||
put(PHONE, contact.address.number.orNull())
|
||||
|
@ -2845,7 +2846,7 @@ open class RecipientDatabase(context: Context, databaseHelper: SignalDatabase) :
|
|||
|
||||
return RecipientRecord(
|
||||
id = recipientId,
|
||||
aci = ACI.parseOrNull(cursor.requireString(ACI_COLUMN)),
|
||||
serviceId = ACI.parseOrNull(cursor.requireString(SERVICE_ID)),
|
||||
pni = PNI.parseOrNull(cursor.requireString(PNI_COLUMN)),
|
||||
username = cursor.requireString(USERNAME),
|
||||
e164 = cursor.requireString(PHONE),
|
||||
|
@ -3045,7 +3046,7 @@ open class RecipientDatabase(context: Context, databaseHelper: SignalDatabase) :
|
|||
private fun RecipientRecord.toLogDetails(): RecipientLogDetails {
|
||||
return RecipientLogDetails(
|
||||
id = this.id,
|
||||
aci = this.aci,
|
||||
serviceId = this.serviceId,
|
||||
e164 = this.e164
|
||||
)
|
||||
}
|
||||
|
@ -3357,27 +3358,27 @@ open class RecipientDatabase(context: Context, databaseHelper: SignalDatabase) :
|
|||
/**
|
||||
* We found a matching recipient and can update them with a new ACI.
|
||||
*/
|
||||
data class MatchAndUpdateAci(val id: RecipientId, val aci: ACI, val bundle: LogBundle) : RecipientFetch(bundle)
|
||||
data class MatchAndUpdateAci(val id: RecipientId, val serviceId: ServiceId, val bundle: LogBundle) : RecipientFetch(bundle)
|
||||
|
||||
/**
|
||||
* We found a matching recipient and can insert an ACI as a *new user*.
|
||||
*/
|
||||
data class MatchAndInsertAci(val id: RecipientId, val aci: ACI, val bundle: LogBundle) : RecipientFetch(bundle)
|
||||
data class MatchAndInsertAci(val id: RecipientId, val serviceId: ServiceId, val bundle: LogBundle) : RecipientFetch(bundle)
|
||||
|
||||
/**
|
||||
* The ACI maps to ACI-only recipient, and the E164 maps to a different E164-only recipient. We need to merge the two together.
|
||||
*/
|
||||
data class MatchAndMerge(val aciId: RecipientId, val e164Id: RecipientId, val changedNumber: RecipientId?, val bundle: LogBundle) : RecipientFetch(bundle)
|
||||
data class MatchAndMerge(val sidId: RecipientId, val e164Id: RecipientId, val changedNumber: RecipientId?, val bundle: LogBundle) : RecipientFetch(bundle)
|
||||
|
||||
/**
|
||||
* We don't have a matching recipient, so we need to insert one.
|
||||
*/
|
||||
data class Insert(val aci: ACI?, val e164: String?, val bundle: LogBundle) : RecipientFetch(bundle)
|
||||
data class Insert(val serviceId: ServiceId?, val e164: String?, val bundle: LogBundle) : RecipientFetch(bundle)
|
||||
|
||||
/**
|
||||
* We need to create a new recipient and give it the E164 of an existing recipient.
|
||||
*/
|
||||
data class InsertAndReassignE164(val aci: ACI?, val e164: String?, val e164Id: RecipientId, val bundle: LogBundle) : RecipientFetch(bundle)
|
||||
data class InsertAndReassignE164(val serviceId: ServiceId?, val e164: String?, val e164Id: RecipientId, val bundle: LogBundle) : RecipientFetch(bundle)
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -3385,9 +3386,9 @@ open class RecipientDatabase(context: Context, databaseHelper: SignalDatabase) :
|
|||
*/
|
||||
private data class LogBundle(
|
||||
val label: String,
|
||||
val aci: ACI? = null,
|
||||
val serviceId: ServiceId? = null,
|
||||
val e164: String? = null,
|
||||
val byAci: RecipientLogDetails? = null,
|
||||
val bySid: RecipientLogDetails? = null,
|
||||
val byE164: RecipientLogDetails? = null
|
||||
) {
|
||||
fun label(label: String): LogBundle {
|
||||
|
@ -3400,7 +3401,7 @@ open class RecipientDatabase(context: Context, databaseHelper: SignalDatabase) :
|
|||
*/
|
||||
private data class RecipientLogDetails(
|
||||
val id: RecipientId,
|
||||
val aci: ACI? = null,
|
||||
val serviceId: ServiceId? = null,
|
||||
val e164: String? = null
|
||||
)
|
||||
}
|
||||
|
|
|
@ -133,7 +133,7 @@ public class SenderKeyDatabase extends Database {
|
|||
public Cursor getAllCreatedBySelf() {
|
||||
SQLiteDatabase db = databaseHelper.getSignalReadableDatabase();
|
||||
String query = ADDRESS + " = ?";
|
||||
String[] args = SqlUtil.buildArgs(Recipient.self().requireAci());
|
||||
String[] args = SqlUtil.buildArgs(Recipient.self().requireServiceId());
|
||||
|
||||
return db.query(TABLE_NAME, new String[]{ ID, DISTRIBUTION_ID, CREATED_AT }, query, args, null, null, CREATED_AT + " DESC");
|
||||
}
|
||||
|
|
|
@ -145,8 +145,8 @@ public class SenderKeySharedDatabase extends Database {
|
|||
SQLiteDatabase db = databaseHelper.getSignalWritableDatabase();
|
||||
Recipient recipient = Recipient.resolved(recipientId);
|
||||
|
||||
if (recipient.hasAci()) {
|
||||
db.delete(TABLE_NAME, ADDRESS + " = ?", SqlUtil.buildArgs(recipient.requireAci().toString()));
|
||||
if (recipient.hasServiceId()) {
|
||||
db.delete(TABLE_NAME, ADDRESS + " = ?", SqlUtil.buildArgs(recipient.requireServiceId().toString()));
|
||||
} else {
|
||||
Log.w(TAG, "Recipient doesn't have a UUID! " + recipientId);
|
||||
}
|
||||
|
|
|
@ -6,7 +6,7 @@ import org.thoughtcrime.securesms.util.CursorUtil
|
|||
import org.thoughtcrime.securesms.util.SqlUtil
|
||||
import org.whispersystems.libsignal.SignalProtocolAddress
|
||||
import org.whispersystems.libsignal.state.SessionRecord
|
||||
import org.whispersystems.signalservice.api.push.AccountIdentifier
|
||||
import org.whispersystems.signalservice.api.push.ServiceId
|
||||
import org.whispersystems.signalservice.api.push.SignalServiceAddress
|
||||
import java.io.IOException
|
||||
import java.util.ArrayList
|
||||
|
@ -36,12 +36,12 @@ class SessionDatabase(context: Context, databaseHelper: SignalDatabase) : Databa
|
|||
"""
|
||||
}
|
||||
|
||||
fun store(accountId: AccountIdentifier, address: SignalProtocolAddress, record: SessionRecord) {
|
||||
fun store(serviceId: ServiceId, address: SignalProtocolAddress, record: SessionRecord) {
|
||||
require(address.name[0] != '+') { "Cannot insert an e164 into this table!" }
|
||||
|
||||
writableDatabase.compileStatement("INSERT INTO $TABLE_NAME ($ACCOUNT_ID, $ADDRESS, $DEVICE, $RECORD) VALUES (?, ?, ?, ?) ON CONFLICT ($ACCOUNT_ID, $ADDRESS, $DEVICE) DO UPDATE SET $RECORD = excluded.$RECORD").use { statement ->
|
||||
statement.apply {
|
||||
bindString(1, accountId.toString())
|
||||
bindString(1, serviceId.toString())
|
||||
bindString(2, address.name)
|
||||
bindLong(3, address.deviceId.toLong())
|
||||
bindBlob(4, record.serialize())
|
||||
|
@ -50,10 +50,10 @@ class SessionDatabase(context: Context, databaseHelper: SignalDatabase) : Databa
|
|||
}
|
||||
}
|
||||
|
||||
fun load(accountId: AccountIdentifier, address: SignalProtocolAddress): SessionRecord? {
|
||||
fun load(serviceId: ServiceId, address: SignalProtocolAddress): SessionRecord? {
|
||||
val projection = arrayOf(RECORD)
|
||||
val selection = "$ACCOUNT_ID = ? AND $ADDRESS = ? AND $DEVICE = ?"
|
||||
val args = SqlUtil.buildArgs(accountId, address.name, address.deviceId)
|
||||
val args = SqlUtil.buildArgs(serviceId, address.name, address.deviceId)
|
||||
|
||||
readableDatabase.query(TABLE_NAME, projection, selection, args, null, null, null).use { cursor ->
|
||||
if (cursor.moveToFirst()) {
|
||||
|
@ -68,14 +68,14 @@ class SessionDatabase(context: Context, databaseHelper: SignalDatabase) : Databa
|
|||
return null
|
||||
}
|
||||
|
||||
fun load(accountId: AccountIdentifier, addresses: List<SignalProtocolAddress>): List<SessionRecord?> {
|
||||
fun load(serviceId: ServiceId, addresses: List<SignalProtocolAddress>): List<SessionRecord?> {
|
||||
val projection = arrayOf(ADDRESS, DEVICE, RECORD)
|
||||
val query = "$ACCOUNT_ID = ? AND $ADDRESS = ? AND $DEVICE = ?"
|
||||
val args: MutableList<Array<String>> = ArrayList(addresses.size)
|
||||
val sessions: HashMap<SignalProtocolAddress, SessionRecord?> = LinkedHashMap(addresses.size)
|
||||
|
||||
for (address in addresses) {
|
||||
args.add(SqlUtil.buildArgs(accountId, address.name, address.deviceId))
|
||||
args.add(SqlUtil.buildArgs(serviceId, address.name, address.deviceId))
|
||||
sessions[address] = null
|
||||
}
|
||||
|
||||
|
@ -97,10 +97,10 @@ class SessionDatabase(context: Context, databaseHelper: SignalDatabase) : Databa
|
|||
return sessions.values.toList()
|
||||
}
|
||||
|
||||
fun getAllFor(accountId: AccountIdentifier, addressName: String): List<SessionRow> {
|
||||
fun getAllFor(serviceId: ServiceId, addressName: String): List<SessionRow> {
|
||||
val results: MutableList<SessionRow> = mutableListOf()
|
||||
|
||||
readableDatabase.query(TABLE_NAME, null, "$ACCOUNT_ID = ? AND $ADDRESS = ?", SqlUtil.buildArgs(accountId, addressName), null, null, null).use { cursor ->
|
||||
readableDatabase.query(TABLE_NAME, null, "$ACCOUNT_ID = ? AND $ADDRESS = ?", SqlUtil.buildArgs(serviceId, addressName), null, null, null).use { cursor ->
|
||||
while (cursor.moveToNext()) {
|
||||
try {
|
||||
results.add(
|
||||
|
@ -118,12 +118,12 @@ class SessionDatabase(context: Context, databaseHelper: SignalDatabase) : Databa
|
|||
return results
|
||||
}
|
||||
|
||||
fun getAllFor(accountId: AccountIdentifier, addressNames: List<String?>): List<SessionRow> {
|
||||
fun getAllFor(serviceId: ServiceId, addressNames: List<String?>): List<SessionRow> {
|
||||
val query: SqlUtil.Query = SqlUtil.buildCollectionQuery(ADDRESS, addressNames)
|
||||
val results: MutableList<SessionRow> = LinkedList()
|
||||
|
||||
val queryString = "$ACCOUNT_ID = ? AND (${query.where})"
|
||||
val queryArgs: Array<String> = arrayOf(accountId.toString()) + query.whereArgs
|
||||
val queryArgs: Array<String> = arrayOf(serviceId.toString()) + query.whereArgs
|
||||
|
||||
readableDatabase.query(TABLE_NAME, null, queryString, queryArgs, null, null, null).use { cursor ->
|
||||
while (cursor.moveToNext()) {
|
||||
|
@ -143,10 +143,10 @@ class SessionDatabase(context: Context, databaseHelper: SignalDatabase) : Databa
|
|||
return results
|
||||
}
|
||||
|
||||
fun getAll(accountId: AccountIdentifier): List<SessionRow> {
|
||||
fun getAll(serviceId: ServiceId): List<SessionRow> {
|
||||
val results: MutableList<SessionRow> = mutableListOf()
|
||||
|
||||
readableDatabase.query(TABLE_NAME, null, "$ACCOUNT_ID = ?", SqlUtil.buildArgs(accountId), null, null, null).use { cursor ->
|
||||
readableDatabase.query(TABLE_NAME, null, "$ACCOUNT_ID = ?", SqlUtil.buildArgs(serviceId), null, null, null).use { cursor ->
|
||||
while (cursor.moveToNext()) {
|
||||
try {
|
||||
results.add(
|
||||
|
@ -164,10 +164,10 @@ class SessionDatabase(context: Context, databaseHelper: SignalDatabase) : Databa
|
|||
return results
|
||||
}
|
||||
|
||||
fun getSubDevices(accountId: AccountIdentifier, addressName: String): List<Int> {
|
||||
fun getSubDevices(serviceId: ServiceId, addressName: String): List<Int> {
|
||||
val projection = arrayOf(DEVICE)
|
||||
val selection = "$ACCOUNT_ID = ? AND $ADDRESS = ? AND $DEVICE != ?"
|
||||
val args = SqlUtil.buildArgs(accountId, addressName, SignalServiceAddress.DEFAULT_DEVICE_ID)
|
||||
val args = SqlUtil.buildArgs(serviceId, addressName, SignalServiceAddress.DEFAULT_DEVICE_ID)
|
||||
|
||||
val results: MutableList<Int> = mutableListOf()
|
||||
|
||||
|
@ -179,17 +179,17 @@ class SessionDatabase(context: Context, databaseHelper: SignalDatabase) : Databa
|
|||
return results
|
||||
}
|
||||
|
||||
fun delete(accountId: AccountIdentifier, address: SignalProtocolAddress) {
|
||||
writableDatabase.delete(TABLE_NAME, "$ACCOUNT_ID = ? AND $ADDRESS = ? AND $DEVICE = ?", SqlUtil.buildArgs(accountId, address.name, address.deviceId))
|
||||
fun delete(serviceId: ServiceId, address: SignalProtocolAddress) {
|
||||
writableDatabase.delete(TABLE_NAME, "$ACCOUNT_ID = ? AND $ADDRESS = ? AND $DEVICE = ?", SqlUtil.buildArgs(serviceId, address.name, address.deviceId))
|
||||
}
|
||||
|
||||
fun deleteAllFor(accountId: AccountIdentifier, addressName: String) {
|
||||
writableDatabase.delete(TABLE_NAME, "$ACCOUNT_ID = ? AND $ADDRESS = ?", SqlUtil.buildArgs(accountId, addressName))
|
||||
fun deleteAllFor(serviceId: ServiceId, addressName: String) {
|
||||
writableDatabase.delete(TABLE_NAME, "$ACCOUNT_ID = ? AND $ADDRESS = ?", SqlUtil.buildArgs(serviceId, addressName))
|
||||
}
|
||||
|
||||
fun hasSessionFor(accountId: AccountIdentifier, addressName: String): Boolean {
|
||||
fun hasSessionFor(serviceId: ServiceId, addressName: String): Boolean {
|
||||
val query = "$ACCOUNT_ID = ? AND $ADDRESS = ?"
|
||||
val args = SqlUtil.buildArgs(accountId, addressName)
|
||||
val args = SqlUtil.buildArgs(serviceId, addressName)
|
||||
readableDatabase.query(TABLE_NAME, arrayOf("1"), query, args, null, null, null, "1").use { cursor ->
|
||||
return cursor.moveToFirst()
|
||||
}
|
||||
|
|
|
@ -9,7 +9,7 @@ import org.whispersystems.libsignal.InvalidKeyException
|
|||
import org.whispersystems.libsignal.ecc.Curve
|
||||
import org.whispersystems.libsignal.ecc.ECKeyPair
|
||||
import org.whispersystems.libsignal.state.SignedPreKeyRecord
|
||||
import org.whispersystems.signalservice.api.push.AccountIdentifier
|
||||
import org.whispersystems.signalservice.api.push.ServiceId
|
||||
import java.io.IOException
|
||||
import java.util.LinkedList
|
||||
|
||||
|
@ -39,8 +39,8 @@ class SignedPreKeyDatabase(context: Context, databaseHelper: SignalDatabase) : D
|
|||
"""
|
||||
}
|
||||
|
||||
fun get(accountId: AccountIdentifier, keyId: Int): SignedPreKeyRecord? {
|
||||
readableDatabase.query(TABLE_NAME, null, "$ACCOUNT_ID = ? AND $KEY_ID = ?", SqlUtil.buildArgs(accountId, keyId), null, null, null).use { cursor ->
|
||||
fun get(serviceId: ServiceId, keyId: Int): SignedPreKeyRecord? {
|
||||
readableDatabase.query(TABLE_NAME, null, "$ACCOUNT_ID = ? AND $KEY_ID = ?", SqlUtil.buildArgs(serviceId, keyId), null, null, null).use { cursor ->
|
||||
if (cursor.moveToFirst()) {
|
||||
try {
|
||||
val publicKey = Curve.decodePoint(Base64.decode(cursor.requireNonNullString(PUBLIC_KEY)), 0)
|
||||
|
@ -58,10 +58,10 @@ class SignedPreKeyDatabase(context: Context, databaseHelper: SignalDatabase) : D
|
|||
return null
|
||||
}
|
||||
|
||||
fun getAll(accountId: AccountIdentifier): List<SignedPreKeyRecord> {
|
||||
fun getAll(serviceId: ServiceId): List<SignedPreKeyRecord> {
|
||||
val results: MutableList<SignedPreKeyRecord> = LinkedList()
|
||||
|
||||
readableDatabase.query(TABLE_NAME, null, "$ACCOUNT_ID = ?", SqlUtil.buildArgs(accountId), null, null, null).use { cursor ->
|
||||
readableDatabase.query(TABLE_NAME, null, "$ACCOUNT_ID = ?", SqlUtil.buildArgs(serviceId), null, null, null).use { cursor ->
|
||||
while (cursor.moveToNext()) {
|
||||
try {
|
||||
val keyId = cursor.requireInt(KEY_ID)
|
||||
|
@ -81,9 +81,9 @@ class SignedPreKeyDatabase(context: Context, databaseHelper: SignalDatabase) : D
|
|||
return results
|
||||
}
|
||||
|
||||
fun insert(accountId: AccountIdentifier, keyId: Int, record: SignedPreKeyRecord) {
|
||||
fun insert(serviceId: ServiceId, keyId: Int, record: SignedPreKeyRecord) {
|
||||
val contentValues = contentValuesOf(
|
||||
ACCOUNT_ID to accountId.toString(),
|
||||
ACCOUNT_ID to serviceId.toString(),
|
||||
KEY_ID to keyId,
|
||||
PUBLIC_KEY to Base64.encodeBytes(record.keyPair.publicKey.serialize()),
|
||||
PRIVATE_KEY to Base64.encodeBytes(record.keyPair.privateKey.serialize()),
|
||||
|
@ -93,7 +93,7 @@ class SignedPreKeyDatabase(context: Context, databaseHelper: SignalDatabase) : D
|
|||
writableDatabase.replace(TABLE_NAME, null, contentValues)
|
||||
}
|
||||
|
||||
fun delete(accountId: AccountIdentifier, keyId: Int) {
|
||||
writableDatabase.delete(TABLE_NAME, "$ACCOUNT_ID = ? AND $KEY_ID = ?", SqlUtil.buildArgs(accountId, keyId))
|
||||
fun delete(serviceId: ServiceId, keyId: Int) {
|
||||
writableDatabase.delete(TABLE_NAME, "$ACCOUNT_ID = ? AND $KEY_ID = ?", SqlUtil.buildArgs(serviceId, keyId))
|
||||
}
|
||||
}
|
||||
|
|
|
@ -719,11 +719,11 @@ public class SmsDatabase extends MessageDatabase {
|
|||
|
||||
if (!peerEraIdSameAsPrevious && !Util.isEmpty(peekGroupCallEraId)) {
|
||||
Recipient self = Recipient.self();
|
||||
boolean markRead = peekJoinedUuids.contains(self.requireAci().uuid()) || self.getId().equals(sender);
|
||||
boolean markRead = peekJoinedUuids.contains(self.requireServiceId().uuid()) || self.getId().equals(sender);
|
||||
|
||||
byte[] updateDetails = GroupCallUpdateDetails.newBuilder()
|
||||
.setEraId(Util.emptyIfNull(peekGroupCallEraId))
|
||||
.setStartedCallUuid(Recipient.resolved(sender).requireAci().toString())
|
||||
.setStartedCallUuid(Recipient.resolved(sender).requireServiceId().toString())
|
||||
.setStartedCallTimestamp(timestamp)
|
||||
.addAllInCallUuids(Stream.of(peekJoinedUuids).map(UUID::toString).toList())
|
||||
.setIsCallFull(isCallFull)
|
||||
|
@ -800,7 +800,7 @@ public class SmsDatabase extends MessageDatabase {
|
|||
if (!sameEraId && !Util.isEmpty(messageGroupCallEraId)) {
|
||||
byte[] updateDetails = GroupCallUpdateDetails.newBuilder()
|
||||
.setEraId(Util.emptyIfNull(messageGroupCallEraId))
|
||||
.setStartedCallUuid(Recipient.resolved(sender).requireAci().toString())
|
||||
.setStartedCallUuid(Recipient.resolved(sender).requireServiceId().toString())
|
||||
.setStartedCallTimestamp(timestamp)
|
||||
.addAllInCallUuids(Collections.emptyList())
|
||||
.setIsCallFull(false)
|
||||
|
@ -849,7 +849,7 @@ public class SmsDatabase extends MessageDatabase {
|
|||
}
|
||||
|
||||
GroupCallUpdateDetails groupCallUpdateDetails = GroupCallUpdateDetailsUtil.parse(record.getBody());
|
||||
boolean containsSelf = peekJoinedUuids.contains(Recipient.self().requireAci().uuid());
|
||||
boolean containsSelf = peekJoinedUuids.contains(Recipient.self().requireServiceId().uuid());
|
||||
|
||||
sameEraId = groupCallUpdateDetails.getEraId().equals(peekGroupCallEraId) && !Util.isEmpty(peekGroupCallEraId);
|
||||
|
||||
|
|
|
@ -1208,7 +1208,7 @@ public class ThreadDatabase extends Database {
|
|||
Recipient pinnedRecipient;
|
||||
|
||||
if (pinned.getContact().isPresent()) {
|
||||
pinnedRecipient = Recipient.externalPush(context, pinned.getContact().get());
|
||||
pinnedRecipient = Recipient.externalPush(pinned.getContact().get());
|
||||
} else if (pinned.getGroupV1Id().isPresent()) {
|
||||
try {
|
||||
pinnedRecipient = Recipient.externalGroupExact(context, GroupId.v1(pinned.getGroupV1Id().get()));
|
||||
|
|
|
@ -6,11 +6,12 @@ import androidx.annotation.NonNull;
|
|||
|
||||
import org.thoughtcrime.securesms.R;
|
||||
import org.thoughtcrime.securesms.database.model.databaseprotos.GroupCallUpdateDetails;
|
||||
import org.thoughtcrime.securesms.keyvalue.SignalStore;
|
||||
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.push.ACI;
|
||||
import org.whispersystems.signalservice.api.push.ServiceId;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
@ -22,13 +23,13 @@ import java.util.Objects;
|
|||
*/
|
||||
public class GroupCallUpdateMessageFactory implements UpdateDescription.StringFactory {
|
||||
private final Context context;
|
||||
private final List<ACI> joinedMembers;
|
||||
private final List<ServiceId> joinedMembers;
|
||||
private final boolean withTime;
|
||||
private final GroupCallUpdateDetails groupCallUpdateDetails;
|
||||
private final ACI selfAci;
|
||||
|
||||
public GroupCallUpdateMessageFactory(@NonNull Context context,
|
||||
@NonNull List<ACI> joinedMembers,
|
||||
@NonNull List<ServiceId> joinedMembers,
|
||||
boolean withTime,
|
||||
@NonNull GroupCallUpdateDetails groupCallUpdateDetails)
|
||||
{
|
||||
|
@ -36,7 +37,7 @@ public class GroupCallUpdateMessageFactory implements UpdateDescription.StringFa
|
|||
this.joinedMembers = new ArrayList<>(joinedMembers);
|
||||
this.withTime = withTime;
|
||||
this.groupCallUpdateDetails = groupCallUpdateDetails;
|
||||
this.selfAci = Recipient.self().requireAci();
|
||||
this.selfAci = SignalStore.account().requireAci();
|
||||
|
||||
boolean removed = this.joinedMembers.remove(selfAci);
|
||||
if (removed) {
|
||||
|
@ -87,12 +88,12 @@ public class GroupCallUpdateMessageFactory implements UpdateDescription.StringFa
|
|||
}
|
||||
}
|
||||
|
||||
private @NonNull String describe(@NonNull ACI aci) {
|
||||
if (aci.isUnknown()) {
|
||||
private @NonNull String describe(@NonNull ServiceId serviceId) {
|
||||
if (serviceId.isUnknown()) {
|
||||
return context.getString(R.string.MessageRecord_unknown);
|
||||
}
|
||||
|
||||
Recipient recipient = Recipient.resolved(RecipientId.from(aci, null));
|
||||
Recipient recipient = Recipient.resolved(RecipientId.from(serviceId, null));
|
||||
|
||||
if (recipient.isSelf()) {
|
||||
return context.getString(R.string.MessageRecord_you);
|
||||
|
|
|
@ -27,6 +27,7 @@ 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.push.ServiceId;
|
||||
import org.whispersystems.signalservice.api.util.UuidUtil;
|
||||
|
||||
import java.util.Arrays;
|
||||
|
@ -746,11 +747,11 @@ final class GroupsV2UpdateMessageProducer {
|
|||
|
||||
/**
|
||||
* Map an ACI to a string that describes the group member.
|
||||
* @param aci
|
||||
* @param serviceId
|
||||
*/
|
||||
@NonNull
|
||||
@WorkerThread
|
||||
String describe(@NonNull ACI aci);
|
||||
String describe(@NonNull ServiceId serviceId);
|
||||
}
|
||||
|
||||
private interface StringFactory1Arg {
|
||||
|
@ -771,9 +772,9 @@ final class GroupsV2UpdateMessageProducer {
|
|||
@NonNull StringFactory1Arg stringFactory,
|
||||
@DrawableRes int iconResource)
|
||||
{
|
||||
ACI aci1 = ACI.fromByteStringOrUnknown(uuid1Bytes);
|
||||
ServiceId serviceId = ServiceId.fromByteStringOrUnknown(uuid1Bytes);
|
||||
|
||||
return UpdateDescription.mentioning(Collections.singletonList(aci1), () -> stringFactory.create(descriptionStrategy.describe(aci1)), iconResource);
|
||||
return UpdateDescription.mentioning(Collections.singletonList(serviceId), () -> stringFactory.create(descriptionStrategy.describe(serviceId)), iconResource);
|
||||
}
|
||||
|
||||
private UpdateDescription updateDescription(@NonNull ByteString uuid1Bytes,
|
||||
|
@ -781,9 +782,9 @@ final class GroupsV2UpdateMessageProducer {
|
|||
@NonNull StringFactory2Args stringFactory,
|
||||
@DrawableRes int iconResource)
|
||||
{
|
||||
ACI aci1 = ACI.fromByteStringOrUnknown(uuid1Bytes);
|
||||
ACI aci2 = ACI.fromByteStringOrUnknown(uuid2Bytes);
|
||||
ServiceId sid1 = ServiceId.fromByteStringOrUnknown(uuid1Bytes);
|
||||
ServiceId sid2 = ServiceId.fromByteStringOrUnknown(uuid2Bytes);
|
||||
|
||||
return UpdateDescription.mentioning(Arrays.asList(aci1, aci2), () -> stringFactory.create(descriptionStrategy.describe(aci1), descriptionStrategy.describe(aci2)), iconResource);
|
||||
return UpdateDescription.mentioning(Arrays.asList(sid1, sid2), () -> stringFactory.create(descriptionStrategy.describe(sid1), descriptionStrategy.describe(sid2)), iconResource);
|
||||
}
|
||||
}
|
|
@ -60,7 +60,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.push.ServiceId;
|
||||
import org.whispersystems.signalservice.api.util.UuidUtil;
|
||||
|
||||
import java.io.IOException;
|
||||
|
@ -253,7 +253,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().requireAci().uuid()));
|
||||
change.getEditor().equals(UuidUtil.toByteString(Recipient.self().requireServiceId().uuid()));
|
||||
}
|
||||
|
||||
public static @NonNull UpdateDescription getGv2ChangeDescription(@NonNull Context context, @NonNull String body) {
|
||||
|
@ -261,7 +261,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().requireAci().uuid());
|
||||
GroupsV2UpdateMessageProducer updateMessageProducer = new GroupsV2UpdateMessageProducer(context, descriptionStrategy, Recipient.self().requireServiceId().uuid());
|
||||
|
||||
if (decryptedGroupV2Context.hasChange() && (decryptedGroupV2Context.getGroupState().getRevision() != 0 || decryptedGroupV2Context.hasPreviousGroupState())) {
|
||||
return UpdateDescription.concatWithNewLines(updateMessageProducer.describeChanges(decryptedGroupV2Context.getPreviousGroupState(), decryptedGroupV2Context.getChange()));
|
||||
|
@ -292,7 +292,7 @@ public abstract class MessageRecord extends DisplayRecord {
|
|||
}
|
||||
|
||||
DecryptedGroup groupState = decryptedGroupV2Context.getGroupState();
|
||||
boolean invited = DecryptedGroupUtil.findPendingByUuid(groupState.getPendingMembersList(), Recipient.self().requireAci().uuid()).isPresent();
|
||||
boolean invited = DecryptedGroupUtil.findPendingByUuid(groupState.getPendingMembersList(), Recipient.self().requireServiceId().uuid()).isPresent();
|
||||
|
||||
if (decryptedGroupV2Context.hasChange()) {
|
||||
UUID changeEditor = UuidUtil.fromByteStringOrNull(decryptedGroupV2Context.getChange().getEditor());
|
||||
|
@ -314,7 +314,7 @@ public abstract class MessageRecord extends DisplayRecord {
|
|||
@NonNull Function<Recipient, String> stringGenerator,
|
||||
@DrawableRes int iconResource)
|
||||
{
|
||||
return UpdateDescription.mentioning(Collections.singletonList(recipient.getAci().or(ACI.UNKNOWN)),
|
||||
return UpdateDescription.mentioning(Collections.singletonList(recipient.getServiceId().or(ServiceId.UNKNOWN)),
|
||||
() -> stringGenerator.apply(recipient.resolve()),
|
||||
iconResource);
|
||||
}
|
||||
|
@ -382,11 +382,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<ACI> joinedMembers = Stream.of(groupCallUpdateDetails.getInCallUuidsList())
|
||||
.map(UuidUtil::parseOrNull)
|
||||
.withoutNulls()
|
||||
.map(ACI::from)
|
||||
.toList();
|
||||
List<ServiceId> joinedMembers = Stream.of(groupCallUpdateDetails.getInCallUuidsList())
|
||||
.map(UuidUtil::parseOrNull)
|
||||
.withoutNulls()
|
||||
.map(ServiceId::from)
|
||||
.toList();
|
||||
|
||||
UpdateDescription.StringFactory stringFactory = new GroupCallUpdateMessageFactory(context, joinedMembers, withTime, groupCallUpdateDetails);
|
||||
|
||||
|
@ -421,11 +421,11 @@ public abstract class MessageRecord extends DisplayRecord {
|
|||
}
|
||||
|
||||
@Override
|
||||
public @NonNull String describe(@NonNull ACI aci) {
|
||||
if (aci.isUnknown()) {
|
||||
public @NonNull String describe(@NonNull ServiceId serviceId) {
|
||||
if (serviceId.isUnknown()) {
|
||||
return context.getString(R.string.MessageRecord_unknown);
|
||||
}
|
||||
return Recipient.resolved(RecipientId.from(aci, null)).getDisplayName(context);
|
||||
return Recipient.resolved(RecipientId.from(serviceId, null)).getDisplayName(context);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -20,15 +20,15 @@ import org.thoughtcrime.securesms.recipients.Recipient
|
|||
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 org.whispersystems.signalservice.api.push.PNI
|
||||
import org.whispersystems.signalservice.api.push.ServiceId
|
||||
|
||||
/**
|
||||
* Database model for [RecipientDatabase].
|
||||
*/
|
||||
data class RecipientRecord(
|
||||
val id: RecipientId,
|
||||
val aci: ACI?,
|
||||
val serviceId: ServiceId?,
|
||||
val pni: PNI?,
|
||||
val username: String?,
|
||||
val e164: String?,
|
||||
|
|
|
@ -9,6 +9,7 @@ import androidx.annotation.WorkerThread;
|
|||
|
||||
import org.signal.core.util.ThreadUtil;
|
||||
import org.whispersystems.signalservice.api.push.ACI;
|
||||
import org.whispersystems.signalservice.api.push.ServiceId;
|
||||
import org.whispersystems.signalservice.api.util.UuidUtil;
|
||||
|
||||
import java.util.Collection;
|
||||
|
@ -28,14 +29,14 @@ public final class UpdateDescription {
|
|||
String create();
|
||||
}
|
||||
|
||||
private final Collection<ACI> mentioned;
|
||||
private final StringFactory stringFactory;
|
||||
private final String staticString;
|
||||
private final int lightIconResource;
|
||||
private final int lightTint;
|
||||
private final int darkTint;
|
||||
private final Collection<ServiceId> 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<ACI> mentioned,
|
||||
private UpdateDescription(@NonNull Collection<ServiceId> mentioned,
|
||||
@Nullable StringFactory stringFactory,
|
||||
@Nullable String staticString,
|
||||
@DrawableRes int iconResource,
|
||||
|
@ -60,11 +61,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<ACI> mentioned,
|
||||
public static UpdateDescription mentioning(@NonNull Collection<ServiceId> mentioned,
|
||||
@NonNull StringFactory stringFactory,
|
||||
@DrawableRes int iconResource)
|
||||
{
|
||||
return new UpdateDescription(ACI.filterKnown(mentioned),
|
||||
return new UpdateDescription(ServiceId.filterKnown(mentioned),
|
||||
stringFactory,
|
||||
null,
|
||||
iconResource,
|
||||
|
@ -118,7 +119,7 @@ public final class UpdateDescription {
|
|||
}
|
||||
|
||||
@AnyThread
|
||||
public Collection<ACI> getMentioned() {
|
||||
public Collection<ServiceId> getMentioned() {
|
||||
return mentioned;
|
||||
}
|
||||
|
||||
|
@ -149,7 +150,7 @@ public final class UpdateDescription {
|
|||
);
|
||||
}
|
||||
|
||||
Set<ACI> allMentioned = new HashSet<>();
|
||||
Set<ServiceId> allMentioned = new HashSet<>();
|
||||
|
||||
for (UpdateDescription updateDescription : updateDescriptions) {
|
||||
allMentioned.addAll(updateDescription.getMentioned());
|
||||
|
|
|
@ -104,7 +104,7 @@ final class GroupManagerV2 {
|
|||
this.groupsV2Operations = ApplicationDependencies.getGroupsV2Operations();
|
||||
this.authorization = ApplicationDependencies.getGroupsV2Authorization();
|
||||
this.groupsV2StateProcessor = ApplicationDependencies.getGroupsV2StateProcessor();
|
||||
this.selfAci = Recipient.self().requireAci();
|
||||
this.selfAci = SignalStore.account().requireAci();
|
||||
this.groupCandidateHelper = new GroupCandidateHelper(context);
|
||||
}
|
||||
|
||||
|
@ -142,7 +142,7 @@ final class GroupManagerV2 {
|
|||
|
||||
Map<UUID, UuidCiphertext> uuidCipherTexts = new HashMap<>();
|
||||
for (Recipient recipient : recipients) {
|
||||
uuidCipherTexts.put(recipient.requireAci().uuid(), clientZkGroupCipher.encryptUuid(recipient.requireAci().uuid()));
|
||||
uuidCipherTexts.put(recipient.requireServiceId().uuid(), clientZkGroupCipher.encryptUuid(recipient.requireServiceId().uuid()));
|
||||
}
|
||||
|
||||
return uuidCipherTexts;
|
||||
|
@ -389,7 +389,7 @@ final class GroupManagerV2 {
|
|||
throws GroupChangeFailedException, GroupInsufficientRightsException, IOException, GroupNotAMemberException
|
||||
{
|
||||
Set<UUID> uuids = Stream.of(recipientIds)
|
||||
.map(r -> Recipient.resolved(r).requireAci().uuid())
|
||||
.map(r -> Recipient.resolved(r).requireServiceId().uuid())
|
||||
.collect(Collectors.toSet());
|
||||
|
||||
return commitChangeWithConflictResolution(groupOperations.createApproveGroupJoinRequest(uuids));
|
||||
|
@ -400,7 +400,7 @@ final class GroupManagerV2 {
|
|||
throws GroupChangeFailedException, GroupInsufficientRightsException, IOException, GroupNotAMemberException
|
||||
{
|
||||
Set<UUID> uuids = Stream.of(recipientIds)
|
||||
.map(r -> Recipient.resolved(r).requireAci().uuid())
|
||||
.map(r -> Recipient.resolved(r).requireServiceId().uuid())
|
||||
.collect(Collectors.toSet());
|
||||
|
||||
return commitChangeWithConflictResolution(groupOperations.createRefuseGroupJoinRequest(uuids));
|
||||
|
@ -412,7 +412,7 @@ final class GroupManagerV2 {
|
|||
throws GroupChangeFailedException, GroupInsufficientRightsException, IOException, GroupNotAMemberException
|
||||
{
|
||||
Recipient recipient = Recipient.resolved(recipientId);
|
||||
return commitChangeWithConflictResolution(groupOperations.createChangeMemberRole(recipient.requireAci().uuid(), admin ? Member.Role.ADMINISTRATOR : Member.Role.DEFAULT));
|
||||
return commitChangeWithConflictResolution(groupOperations.createChangeMemberRole(recipient.requireServiceId().uuid(), admin ? Member.Role.ADMINISTRATOR : Member.Role.DEFAULT));
|
||||
}
|
||||
|
||||
@WorkerThread
|
||||
|
@ -441,7 +441,7 @@ final class GroupManagerV2 {
|
|||
{
|
||||
Recipient recipient = Recipient.resolved(recipientId);
|
||||
|
||||
return commitChangeWithConflictResolution(groupOperations.createRemoveMembersChange(Collections.singleton(recipient.requireAci().uuid())));
|
||||
return commitChangeWithConflictResolution(groupOperations.createRemoveMembersChange(Collections.singleton(recipient.requireServiceId().uuid())));
|
||||
}
|
||||
|
||||
@WorkerThread
|
||||
|
@ -449,7 +449,7 @@ final class GroupManagerV2 {
|
|||
throws GroupChangeFailedException, GroupNotAMemberException, GroupInsufficientRightsException, IOException
|
||||
{
|
||||
Recipient self = Recipient.self();
|
||||
List<UUID> newAdminRecipients = Stream.of(newAdmins).map(id -> Recipient.resolved(id).requireAci().uuid()).toList();
|
||||
List<UUID> newAdminRecipients = Stream.of(newAdmins).map(id -> Recipient.resolved(id).requireServiceId().uuid()).toList();
|
||||
|
||||
return commitChangeWithConflictResolution(groupOperations.createLeaveAndPromoteMembersToAdmin(selfAci.uuid(),
|
||||
newAdminRecipients));
|
||||
|
|
|
@ -19,6 +19,7 @@ import org.thoughtcrime.securesms.recipients.Recipient;
|
|||
import org.thoughtcrime.securesms.recipients.RecipientId;
|
||||
import org.whispersystems.signalservice.api.groupsv2.PartialDecryptedGroup;
|
||||
import org.whispersystems.signalservice.api.push.ACI;
|
||||
import org.whispersystems.signalservice.api.push.ServiceId;
|
||||
import org.whispersystems.signalservice.api.util.UuidUtil;
|
||||
import org.whispersystems.signalservice.internal.push.SignalServiceProtos;
|
||||
|
||||
|
@ -85,24 +86,24 @@ public final class GroupProtoUtil {
|
|||
|
||||
@WorkerThread
|
||||
public static Recipient uuidByteStringToRecipient(@NonNull Context context, @NonNull ByteString uuidByteString) {
|
||||
ACI aci = ACI.fromByteString(uuidByteString);
|
||||
ServiceId serviceId = ACI.fromByteString(uuidByteString);
|
||||
|
||||
if (aci.isUnknown()) {
|
||||
if (serviceId.isUnknown()) {
|
||||
return Recipient.UNKNOWN;
|
||||
}
|
||||
|
||||
return Recipient.externalPush(context, aci, null, false);
|
||||
return Recipient.externalPush(serviceId, null, false);
|
||||
}
|
||||
|
||||
@WorkerThread
|
||||
public static @NonNull RecipientId uuidByteStringToRecipientId(@NonNull ByteString uuidByteString) {
|
||||
ACI aci = ACI.fromByteString(uuidByteString);
|
||||
ServiceId serviceId = ACI.fromByteString(uuidByteString);
|
||||
|
||||
if (aci.isUnknown()) {
|
||||
if (serviceId.isUnknown()) {
|
||||
return RecipientId.UNKNOWN;
|
||||
}
|
||||
|
||||
return RecipientId.from(aci, null);
|
||||
return RecipientId.from(serviceId, null);
|
||||
}
|
||||
|
||||
public static boolean isMember(@NonNull UUID uuid, @NonNull List<DecryptedMember> membersList) {
|
||||
|
|
|
@ -99,7 +99,7 @@ public final class GroupV1MessageProcessor {
|
|||
|
||||
if (group.getMembers().isPresent()) {
|
||||
for (SignalServiceAddress member : group.getMembers().get()) {
|
||||
members.add(Recipient.externalGV1Member(context, member).getId());
|
||||
members.add(Recipient.externalGV1Member(member).getId());
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -131,7 +131,7 @@ public final class GroupV1MessageProcessor {
|
|||
|
||||
if (group.getMembers().isPresent()) {
|
||||
for (SignalServiceAddress messageMember : group.getMembers().get()) {
|
||||
messageMembers.add(Recipient.externalGV1Member(context, messageMember).getId());
|
||||
messageMembers.add(Recipient.externalGV1Member(messageMember).getId());
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -232,7 +232,7 @@ 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.hasAci() &&
|
||||
return recipient.hasServiceId() &&
|
||||
recipient.getGroupsV2Capability() == Recipient.Capability.SUPPORTED &&
|
||||
recipient.getGroupsV1MigrationCapability() == Recipient.Capability.SUPPORTED &&
|
||||
recipient.getRegistered() == RecipientDatabase.RegisteredState.REGISTERED &&
|
||||
|
|
|
@ -91,7 +91,7 @@ public final class GroupsV2CapabilityChecker {
|
|||
}
|
||||
}
|
||||
|
||||
if (!member.hasAci()) {
|
||||
if (!member.hasServiceId()) {
|
||||
noUuidCount++;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -28,6 +28,7 @@ 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.push.ServiceId;
|
||||
import org.whispersystems.signalservice.api.util.UuidUtil;
|
||||
|
||||
import java.util.Collections;
|
||||
|
@ -109,7 +110,7 @@ public final class LiveGroup {
|
|||
|
||||
return Stream.of(requestingMembersList)
|
||||
.map(requestingMember -> {
|
||||
Recipient recipient = Recipient.externalPush(ApplicationDependencies.getApplication(), ACI.fromByteString(requestingMember.getUuid()), null, false);
|
||||
Recipient recipient = Recipient.externalPush(ServiceId.fromByteString(requestingMember.getUuid()), null, false);
|
||||
return new GroupMemberEntry.RequestingMember(recipient, selfAdmin);
|
||||
})
|
||||
.toList();
|
||||
|
|
|
@ -54,7 +54,7 @@ final class PendingMemberInvitesRepository {
|
|||
List<DecryptedPendingMember> pendingMembersList = decryptedGroup.getPendingMembersList();
|
||||
List<SinglePendingMemberInvitedByYou> byMe = new ArrayList<>(pendingMembersList.size());
|
||||
List<MultiplePendingMembersInvitedByAnother> byOthers = new ArrayList<>(pendingMembersList.size());
|
||||
ByteString self = Recipient.self().requireAci().toByteString();
|
||||
ByteString self = Recipient.self().requireServiceId().toByteString();
|
||||
boolean selfIsAdmin = v2GroupProperties.isAdmin(Recipient.self());
|
||||
|
||||
Stream.of(pendingMembersList)
|
||||
|
|
|
@ -95,7 +95,7 @@ final class GroupsV1MigrationRepository {
|
|||
group = group.fresh();
|
||||
|
||||
List<Recipient> ineligible = Stream.of(group.getParticipants())
|
||||
.filter(r -> !r.hasAci() ||
|
||||
.filter(r -> !r.hasServiceId() ||
|
||||
r.getGroupsV2Capability() != Recipient.Capability.SUPPORTED ||
|
||||
r.getGroupsV1MigrationCapability() != Recipient.Capability.SUPPORTED ||
|
||||
r.getRegistered() != RecipientDatabase.RegisteredState.REGISTERED)
|
||||
|
|
|
@ -18,6 +18,7 @@ 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 org.whispersystems.signalservice.api.push.ServiceId;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.Collection;
|
||||
|
@ -47,13 +48,13 @@ public final class GroupCandidateHelper {
|
|||
{
|
||||
final Recipient recipient = Recipient.resolved(recipientId);
|
||||
|
||||
ACI aci = recipient.getAci().orNull();
|
||||
if (aci == null) {
|
||||
ServiceId serviceId = recipient.getServiceId().orNull();
|
||||
if (serviceId == null) {
|
||||
throw new AssertionError("Non UUID members should have need detected by now");
|
||||
}
|
||||
|
||||
Optional<ProfileKeyCredential> profileKeyCredential = Optional.fromNullable(recipient.getProfileKeyCredential());
|
||||
GroupCandidate candidate = new GroupCandidate(aci.uuid(), profileKeyCredential);
|
||||
GroupCandidate candidate = new GroupCandidate(serviceId.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<ProfileKeyCredential> profileKeyCredentialOptional = signalServiceAccountManager.resolveProfileKeyCredential(aci, profileKey, Locale.getDefault());
|
||||
Optional<ProfileKeyCredential> profileKeyCredentialOptional = signalServiceAccountManager.resolveProfileKeyCredential(serviceId, profileKey, Locale.getDefault());
|
||||
|
||||
if (profileKeyCredentialOptional.isPresent()) {
|
||||
boolean updatedProfileKey = recipientDatabase.setProfileKeyCredential(recipient.getId(), profileKey, profileKeyCredentialOptional.get());
|
||||
|
|
|
@ -103,7 +103,7 @@ public final class GroupsV2StateProcessor {
|
|||
}
|
||||
|
||||
public StateProcessorForGroup forGroup(@NonNull GroupMasterKey groupMasterKey) {
|
||||
ACI selfAci = Recipient.self().requireAci();
|
||||
ACI selfAci = SignalStore.account().requireAci();
|
||||
ProfileAndMessageHelper profileAndMessageHelper = new ProfileAndMessageHelper(context, selfAci, groupMasterKey, GroupId.v2(groupMasterKey), recipientDatabase);
|
||||
|
||||
return new StateProcessorForGroup(selfAci, context, groupDatabase, groupsV2Api, groupsV2Authorization, groupMasterKey, profileAndMessageHelper);
|
||||
|
@ -546,14 +546,14 @@ public final class GroupsV2StateProcessor {
|
|||
static class ProfileAndMessageHelper {
|
||||
|
||||
private final Context context;
|
||||
private final ACI aci;
|
||||
private final ACI selfAci;
|
||||
private final GroupMasterKey masterKey;
|
||||
private final GroupId.V2 groupId;
|
||||
private final RecipientDatabase recipientDatabase;
|
||||
|
||||
ProfileAndMessageHelper(@NonNull Context context, @NonNull ACI aci, @NonNull GroupMasterKey masterKey, @NonNull GroupId.V2 groupId, @NonNull RecipientDatabase recipientDatabase) {
|
||||
ProfileAndMessageHelper(@NonNull Context context, @NonNull ACI selfAci, @NonNull GroupMasterKey masterKey, @NonNull GroupId.V2 groupId, @NonNull RecipientDatabase recipientDatabase) {
|
||||
this.context = context;
|
||||
this.aci = aci;
|
||||
this.selfAci = selfAci;
|
||||
this.masterKey = masterKey;
|
||||
this.groupId = groupId;
|
||||
this.recipientDatabase = recipientDatabase;
|
||||
|
@ -561,14 +561,14 @@ public final class GroupsV2StateProcessor {
|
|||
|
||||
void determineProfileSharing(@NonNull GlobalGroupState inputGroupState, @NonNull DecryptedGroup newLocalState) {
|
||||
if (inputGroupState.getLocalState() != null) {
|
||||
boolean wasAMemberAlready = DecryptedGroupUtil.findMemberByUuid(inputGroupState.getLocalState().getMembersList(), aci.uuid()).isPresent();
|
||||
boolean wasAMemberAlready = DecryptedGroupUtil.findMemberByUuid(inputGroupState.getLocalState().getMembersList(), selfAci.uuid()).isPresent();
|
||||
|
||||
if (wasAMemberAlready) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
Optional<DecryptedMember> selfAsMemberOptional = DecryptedGroupUtil.findMemberByUuid(newLocalState.getMembersList(), aci.uuid());
|
||||
Optional<DecryptedMember> selfAsMemberOptional = DecryptedGroupUtil.findMemberByUuid(newLocalState.getMembersList(), selfAci.uuid());
|
||||
|
||||
if (selfAsMemberOptional.isPresent()) {
|
||||
DecryptedMember selfAsMember = selfAsMemberOptional.get();
|
||||
|
@ -579,7 +579,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, ACI.fromByteStringOrNull(c.getEditor()), null, false)))
|
||||
.transform(a -> Recipient.externalPush(ACI.fromByteStringOrNull(c.getEditor()), null, false)))
|
||||
.orElse(Optional.absent());
|
||||
|
||||
if (addedByOptional.isPresent()) {
|
||||
|
@ -652,7 +652,7 @@ public final class GroupsV2StateProcessor {
|
|||
void storeMessage(@NonNull DecryptedGroupV2Context decryptedGroupV2Context, long timestamp) {
|
||||
Optional<ACI> editor = getEditor(decryptedGroupV2Context).transform(ACI::from);
|
||||
|
||||
boolean outgoing = !editor.isPresent() || aci.equals(editor.get());
|
||||
boolean outgoing = !editor.isPresent() || selfAci.equals(editor.get());
|
||||
|
||||
if (outgoing) {
|
||||
try {
|
||||
|
@ -690,7 +690,7 @@ public final class GroupsV2StateProcessor {
|
|||
if (changeEditor.isPresent()) {
|
||||
return changeEditor;
|
||||
} else {
|
||||
Optional<DecryptedPendingMember> pendingByUuid = DecryptedGroupUtil.findPendingByUuid(decryptedGroupV2Context.getGroupState().getPendingMembersList(), aci.uuid());
|
||||
Optional<DecryptedPendingMember> pendingByUuid = DecryptedGroupUtil.findPendingByUuid(decryptedGroupV2Context.getGroupState().getPendingMembersList(), selfAci.uuid());
|
||||
if (pendingByUuid.isPresent()) {
|
||||
return Optional.fromNullable(UuidUtil.fromByteStringOrNull(pendingByUuid.get().getAddedByUuid()));
|
||||
}
|
||||
|
|
|
@ -14,7 +14,8 @@ import org.thoughtcrime.securesms.keyvalue.SignalStore;
|
|||
import org.whispersystems.libsignal.state.SignalProtocolStore;
|
||||
import org.whispersystems.libsignal.state.SignedPreKeyRecord;
|
||||
import org.whispersystems.signalservice.api.SignalServiceAccountManager;
|
||||
import org.whispersystems.signalservice.api.push.AccountIdentifier;
|
||||
import org.whispersystems.signalservice.api.push.ServiceId;
|
||||
import org.whispersystems.signalservice.api.push.ServiceIdType;
|
||||
import org.whispersystems.signalservice.api.push.exceptions.PushNetworkException;
|
||||
|
||||
import java.io.IOException;
|
||||
|
@ -70,27 +71,27 @@ public class CreateSignedPreKeyJob extends BaseJob {
|
|||
return;
|
||||
}
|
||||
|
||||
createPreKeys(SignalStore.account().getAci(), ApplicationDependencies.getProtocolStore().aci(), SignalStore.account().aciPreKeys());
|
||||
createPreKeys(SignalStore.account().getPni(), ApplicationDependencies.getProtocolStore().pni(), SignalStore.account().pniPreKeys());
|
||||
createPreKeys(ServiceIdType.ACI, SignalStore.account().getAci(), ApplicationDependencies.getProtocolStore().aci(), SignalStore.account().aciPreKeys());
|
||||
createPreKeys(ServiceIdType.PNI, SignalStore.account().getPni(), ApplicationDependencies.getProtocolStore().pni(), SignalStore.account().pniPreKeys());
|
||||
}
|
||||
|
||||
private void createPreKeys(@Nullable AccountIdentifier accountId, @NonNull SignalProtocolStore protocolStore, @NonNull PreKeyMetadataStore metadataStore)
|
||||
private void createPreKeys(@NonNull ServiceIdType serviceIdType, @Nullable ServiceId serviceId, @NonNull SignalProtocolStore protocolStore, @NonNull PreKeyMetadataStore metadataStore)
|
||||
throws IOException
|
||||
{
|
||||
if (accountId == null) {
|
||||
if (serviceId == null) {
|
||||
warn(TAG, "AccountId not set!");
|
||||
return;
|
||||
}
|
||||
|
||||
if (metadataStore.isSignedPreKeyRegistered()) {
|
||||
warn(TAG, "Signed prekey for " + (accountId.isAci() ? "ACI" : "PNI") + " already registered...");
|
||||
warn(TAG, "Signed prekey for " + serviceIdType + " already registered...");
|
||||
return;
|
||||
}
|
||||
|
||||
SignalServiceAccountManager accountManager = ApplicationDependencies.getSignalServiceAccountManager();
|
||||
SignedPreKeyRecord signedPreKeyRecord = PreKeyUtil.generateAndStoreSignedPreKey(protocolStore, metadataStore, true);
|
||||
|
||||
accountManager.setSignedPreKey(accountId, signedPreKeyRecord);
|
||||
accountManager.setSignedPreKey(serviceIdType, signedPreKeyRecord);
|
||||
metadataStore.setSignedPreKeyRegistered(true);
|
||||
}
|
||||
|
||||
|
|
|
@ -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.hasAci() || recipient.hasE164())) {
|
||||
} else if (recipient.isMaybeRegistered() && (recipient.hasServiceId() || recipient.hasE164())) {
|
||||
blockedIndividuals.add(RecipientUtil.toSignalServiceAddress(context, recipient));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -75,7 +75,7 @@ class MultiDeviceContactSyncJob(parameters: Parameters, private val attachmentPo
|
|||
|
||||
var contact: DeviceContact? = deviceContacts.read()
|
||||
while (contact != null) {
|
||||
val recipient = Recipient.externalPush(context, contact.address.aci, contact.address.number.orNull(), true)
|
||||
val recipient = Recipient.externalPush(contact.address.serviceId, contact.address.number.orNull(), true)
|
||||
|
||||
if (recipient.isSelf) {
|
||||
contact = deviceContacts.read()
|
||||
|
|
|
@ -101,8 +101,8 @@ public class MultiDeviceMessageRequestResponseJob extends BaseJob {
|
|||
SignalServiceMessageSender messageSender = ApplicationDependencies.getSignalServiceMessageSender();
|
||||
Recipient recipient = Recipient.resolved(threadRecipient);
|
||||
|
||||
if (!recipient.hasServiceIdentifier()) {
|
||||
Log.i(TAG, "Queued for recipient without service identifier");
|
||||
if (!recipient.hasServiceId()) {
|
||||
Log.i(TAG, "Queued for recipient without ServiceId");
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
|
@ -91,7 +91,7 @@ public final class MultiDeviceOutgoingPaymentSyncJob extends BaseJob {
|
|||
|
||||
Optional<SignalServiceAddress> uuid;
|
||||
if (!defrag && payment.getPayee().hasRecipientId()) {
|
||||
uuid = Optional.of(new SignalServiceAddress(Recipient.resolved(payment.getPayee().requireRecipientId()).requireAci()));
|
||||
uuid = Optional.of(new SignalServiceAddress(Recipient.resolved(payment.getPayee().requireRecipientId()).requireServiceId()));
|
||||
} else {
|
||||
uuid = Optional.absent();
|
||||
}
|
||||
|
|
|
@ -74,8 +74,8 @@ public final class PushGroupSilentUpdateSendJob extends BaseJob {
|
|||
|
||||
Set<RecipientId> recipients = Stream.concat(Stream.of(memberUuids), Stream.of(pendingUuids))
|
||||
.filter(uuid -> !UuidUtil.UNKNOWN_UUID.equals(uuid))
|
||||
.filter(uuid -> !Recipient.self().requireAci().uuid().equals(uuid))
|
||||
.map(uuid -> Recipient.externalPush(context, ACI.from(uuid), null, false))
|
||||
.filter(uuid -> !Recipient.self().requireServiceId().uuid().equals(uuid))
|
||||
.map(uuid -> Recipient.externalPush(ACI.from(uuid), null, false))
|
||||
.filter(recipient -> recipient.getRegistered() != RecipientDatabase.RegisteredState.NOT_REGISTERED)
|
||||
.map(Recipient::getId)
|
||||
.collect(Collectors.toSet());
|
||||
|
|
|
@ -41,7 +41,6 @@ import org.whispersystems.signalservice.api.messages.SendMessageResult;
|
|||
import org.whispersystems.signalservice.api.messages.SignalServiceAttachment;
|
||||
import org.whispersystems.signalservice.api.messages.SignalServiceDataMessage;
|
||||
import org.whispersystems.signalservice.api.messages.SignalServiceDataMessage.Preview;
|
||||
import org.whispersystems.signalservice.api.messages.multidevice.SignalServiceSyncMessage;
|
||||
import org.whispersystems.signalservice.api.messages.shared.SharedContact;
|
||||
import org.whispersystems.signalservice.api.push.SignalServiceAddress;
|
||||
import org.whispersystems.signalservice.api.push.exceptions.ProofRequiredException;
|
||||
|
@ -75,8 +74,8 @@ public class PushMediaSendJob extends PushSendJob {
|
|||
@WorkerThread
|
||||
public static void enqueue(@NonNull Context context, @NonNull JobManager jobManager, long messageId, @NonNull Recipient recipient) {
|
||||
try {
|
||||
if (!recipient.hasServiceIdentifier()) {
|
||||
throw new AssertionError();
|
||||
if (!recipient.hasServiceId()) {
|
||||
throw new AssertionError("No ServiceId!");
|
||||
}
|
||||
|
||||
MessageDatabase database = SignalDatabase.mms();
|
||||
|
@ -226,7 +225,7 @@ public class PushMediaSendJob extends PushSendJob {
|
|||
.asExpirationUpdate(message.isExpirationUpdate())
|
||||
.build();
|
||||
|
||||
if (Util.equals(SignalStore.account().getAci(), address.getAci())) {
|
||||
if (Util.equals(SignalStore.account().getAci(), address.getServiceId())) {
|
||||
Optional<UnidentifiedAccessPair> syncAccess = UnidentifiedAccessUtil.getAccessForSync(context);
|
||||
SendMessageResult result = messageSender.sendSyncMessage(mediaMessage);
|
||||
SignalDatabase.messageLog().insertIfPossible(messageRecipient.getId(), message.getSentTimeMillis(), result, ContentHint.RESENDABLE, new MessageId(messageId, true));
|
||||
|
|
|
@ -49,17 +49,13 @@ 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.TextSecurePreferences;
|
||||
import org.thoughtcrime.securesms.util.Util;
|
||||
import org.whispersystems.libsignal.util.guava.Optional;
|
||||
import org.whispersystems.signalservice.api.crypto.UnidentifiedAccessPair;
|
||||
import org.whispersystems.signalservice.api.messages.SignalServiceAttachment;
|
||||
import org.whispersystems.signalservice.api.messages.SignalServiceAttachmentPointer;
|
||||
import org.whispersystems.signalservice.api.messages.SignalServiceAttachmentRemoteId;
|
||||
import org.whispersystems.signalservice.api.messages.SignalServiceDataMessage;
|
||||
import org.whispersystems.signalservice.api.messages.SignalServiceDataMessage.Preview;
|
||||
import org.whispersystems.signalservice.api.messages.multidevice.SentTranscriptMessage;
|
||||
import org.whispersystems.signalservice.api.messages.multidevice.SignalServiceSyncMessage;
|
||||
import org.whispersystems.signalservice.api.messages.shared.SharedContact;
|
||||
import org.whispersystems.signalservice.api.push.SignalServiceAddress;
|
||||
import org.whispersystems.signalservice.api.push.exceptions.NonSuccessfulResponseCodeException;
|
||||
|
@ -70,7 +66,6 @@ import java.io.ByteArrayInputStream;
|
|||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.HashSet;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
|
@ -409,7 +404,7 @@ public abstract class PushSendJob extends SendJob {
|
|||
|
||||
List<SignalServiceDataMessage.Mention> getMentionsFor(@NonNull List<Mention> mentions) {
|
||||
return Stream.of(mentions)
|
||||
.map(m -> new SignalServiceDataMessage.Mention(Recipient.resolved(m.getRecipientId()).requireAci(), m.getStart(), m.getLength()))
|
||||
.map(m -> new SignalServiceDataMessage.Mention(Recipient.resolved(m.getRecipientId()).requireServiceId(), m.getStart(), m.getLength()))
|
||||
.toList();
|
||||
}
|
||||
|
||||
|
|
|
@ -31,7 +31,6 @@ import org.whispersystems.signalservice.api.crypto.UnidentifiedAccessPair;
|
|||
import org.whispersystems.signalservice.api.crypto.UntrustedIdentityException;
|
||||
import org.whispersystems.signalservice.api.messages.SendMessageResult;
|
||||
import org.whispersystems.signalservice.api.messages.SignalServiceDataMessage;
|
||||
import org.whispersystems.signalservice.api.messages.multidevice.SignalServiceSyncMessage;
|
||||
import org.whispersystems.signalservice.api.push.SignalServiceAddress;
|
||||
import org.whispersystems.signalservice.api.push.exceptions.ProofRequiredException;
|
||||
import org.whispersystems.signalservice.api.push.exceptions.ServerRejectedException;
|
||||
|
@ -188,7 +187,7 @@ public class PushTextSendJob extends PushSendJob {
|
|||
.asEndSessionMessage(message.isEndSession())
|
||||
.build();
|
||||
|
||||
if (Util.equals(SignalStore.account().getAci(), address.getAci())) {
|
||||
if (Util.equals(SignalStore.account().getAci(), address.getServiceId())) {
|
||||
Optional<UnidentifiedAccessPair> syncAccess = UnidentifiedAccessUtil.getAccessForSync(context);
|
||||
|
||||
SignalLocalMetrics.IndividualMessageSend.onDeliveryStarted(messageId);
|
||||
|
|
|
@ -17,8 +17,9 @@ import org.whispersystems.libsignal.state.SignalProtocolStore;
|
|||
import org.whispersystems.libsignal.state.SignedPreKeyRecord;
|
||||
import org.whispersystems.signalservice.api.SignalServiceAccountManager;
|
||||
import org.whispersystems.signalservice.api.push.ACI;
|
||||
import org.whispersystems.signalservice.api.push.AccountIdentifier;
|
||||
import org.whispersystems.signalservice.api.push.ServiceId;
|
||||
import org.whispersystems.signalservice.api.push.PNI;
|
||||
import org.whispersystems.signalservice.api.push.ServiceIdType;
|
||||
import org.whispersystems.signalservice.api.push.exceptions.NonSuccessfulResponseCodeException;
|
||||
import org.whispersystems.signalservice.api.push.exceptions.PushNetworkException;
|
||||
|
||||
|
@ -81,19 +82,17 @@ public class RefreshPreKeysJob extends BaseJob {
|
|||
return;
|
||||
}
|
||||
|
||||
ACI aci = SignalStore.account().getAci();
|
||||
SignalProtocolStore aciProtocolStore = ApplicationDependencies.getProtocolStore().aci();
|
||||
PreKeyMetadataStore aciPreKeyStore = SignalStore.account().aciPreKeys();
|
||||
|
||||
PNI pni = SignalStore.account().getPni();
|
||||
SignalProtocolStore pniProtocolStore = ApplicationDependencies.getProtocolStore().pni();
|
||||
PreKeyMetadataStore pniPreKeyStore = SignalStore.account().pniPreKeys();
|
||||
|
||||
if (refreshKeys(aci, aciProtocolStore, aciPreKeyStore)) {
|
||||
if (refreshKeys(ServiceIdType.ACI, aciProtocolStore, aciPreKeyStore)) {
|
||||
PreKeyUtil.cleanSignedPreKeys(aciProtocolStore, aciPreKeyStore);
|
||||
}
|
||||
|
||||
if (refreshKeys(pni, pniProtocolStore, pniPreKeyStore)) {
|
||||
if (refreshKeys(ServiceIdType.PNI, pniProtocolStore, pniPreKeyStore)) {
|
||||
PreKeyUtil.cleanSignedPreKeys(pniProtocolStore, pniPreKeyStore);
|
||||
}
|
||||
|
||||
|
@ -104,16 +103,12 @@ public class RefreshPreKeysJob extends BaseJob {
|
|||
/**
|
||||
* @return True if we need to clean prekeys, otherwise false.
|
||||
*/
|
||||
private boolean refreshKeys(@Nullable AccountIdentifier accountId, @NonNull SignalProtocolStore protocolStore, @NonNull PreKeyMetadataStore metadataStore) throws IOException {
|
||||
if (accountId == null) {
|
||||
throw new IOException("Unset identifier!");
|
||||
}
|
||||
|
||||
String logPrefix = "[" + (accountId.isAci() ? "ACI" : "PNI") + "] ";
|
||||
private boolean refreshKeys(@NonNull ServiceIdType serviceIdType, @NonNull SignalProtocolStore protocolStore, @NonNull PreKeyMetadataStore metadataStore) throws IOException {
|
||||
String logPrefix = "[" + serviceIdType + "] ";
|
||||
|
||||
SignalServiceAccountManager accountManager = ApplicationDependencies.getSignalServiceAccountManager();
|
||||
|
||||
int availableKeys = accountManager.getPreKeysCount(accountId);
|
||||
int availableKeys = accountManager.getPreKeysCount(serviceIdType);
|
||||
log(TAG, logPrefix + "Available keys: " + availableKeys);
|
||||
|
||||
if (availableKeys >= PREKEY_MINIMUM && metadataStore.isSignedPreKeyRegistered()) {
|
||||
|
@ -127,7 +122,7 @@ public class RefreshPreKeysJob extends BaseJob {
|
|||
|
||||
log(TAG, logPrefix + "Registering new prekeys...");
|
||||
|
||||
accountManager.setPreKeys(accountId, identityKey.getPublicKey(), signedPreKeyRecord, preKeyRecords);
|
||||
accountManager.setPreKeys(serviceIdType, identityKey.getPublicKey(), signedPreKeyRecord, preKeyRecords);
|
||||
|
||||
metadataStore.setActiveSignedPreKeyId(signedPreKeyRecord.getId());
|
||||
metadataStore.setSignedPreKeyRegistered(true);
|
||||
|
|
|
@ -158,7 +158,7 @@ public class ResendMessageJob extends BaseJob {
|
|||
List<SignalProtocolAddress> addresses = result.getSuccess()
|
||||
.getDevices()
|
||||
.stream()
|
||||
.map(device -> new SignalProtocolAddress(recipient.requireServiceId(), device))
|
||||
.map(device -> recipient.requireServiceId().toProtocolAddress(device))
|
||||
.collect(Collectors.toList());
|
||||
|
||||
ApplicationDependencies.getProtocolStore().aci().markSenderKeySharedWith(distributionId, addresses);
|
||||
|
|
|
@ -47,7 +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.push.ServiceId;
|
||||
import org.whispersystems.signalservice.api.services.ProfileService;
|
||||
import org.whispersystems.signalservice.internal.ServiceResponse;
|
||||
|
||||
|
@ -257,7 +257,7 @@ public class RetrieveProfileJob extends BaseJob {
|
|||
ApplicationDependencies.getSignalWebSocket());
|
||||
|
||||
List<Observable<Pair<Recipient, ServiceResponse<ProfileAndCredential>>>> requests = Stream.of(recipients)
|
||||
.filter(Recipient::hasServiceIdentifier)
|
||||
.filter(Recipient::hasServiceId)
|
||||
.map(r -> ProfileUtil.retrieveProfile(context, r, getRequestType(r), profileService).toObservable())
|
||||
.toList();
|
||||
stopwatch.split("requests");
|
||||
|
@ -288,11 +288,11 @@ public class RetrieveProfileJob extends BaseJob {
|
|||
|
||||
Set<RecipientId> success = SetUtil.difference(recipientIds, operationState.retries);
|
||||
|
||||
Map<RecipientId, ACI> newlyRegistered = Stream.of(operationState.profiles)
|
||||
.map(Pair::first)
|
||||
.filterNot(Recipient::isRegistered)
|
||||
.collect(Collectors.toMap(Recipient::getId,
|
||||
r -> r.getAci().orNull()));
|
||||
Map<RecipientId, ServiceId> newlyRegistered = Stream.of(operationState.profiles)
|
||||
.map(Pair::first)
|
||||
.filterNot(Recipient::isRegistered)
|
||||
.collect(Collectors.toMap(Recipient::getId,
|
||||
r -> r.getServiceId().orNull()));
|
||||
|
||||
|
||||
//noinspection SimplifyStreamApiCallChains
|
||||
|
@ -401,7 +401,7 @@ public class RetrieveProfileJob extends BaseJob {
|
|||
return;
|
||||
}
|
||||
|
||||
IdentityUtil.saveIdentity(recipient.requireServiceId(), identityKey);
|
||||
IdentityUtil.saveIdentity(recipient.requireServiceId().toString(), identityKey);
|
||||
} catch (InvalidKeyException | IOException e) {
|
||||
Log.w(TAG, e);
|
||||
}
|
||||
|
|
|
@ -11,13 +11,13 @@ import org.thoughtcrime.securesms.jobmanager.Data;
|
|||
import org.thoughtcrime.securesms.jobmanager.Job;
|
||||
import org.thoughtcrime.securesms.jobmanager.impl.NetworkConstraint;
|
||||
import org.thoughtcrime.securesms.keyvalue.SignalStore;
|
||||
import org.thoughtcrime.securesms.util.TextSecurePreferences;
|
||||
import org.whispersystems.libsignal.state.SignalProtocolStore;
|
||||
import org.whispersystems.libsignal.state.SignedPreKeyRecord;
|
||||
import org.whispersystems.signalservice.api.SignalServiceAccountManager;
|
||||
import org.whispersystems.signalservice.api.push.ACI;
|
||||
import org.whispersystems.signalservice.api.push.AccountIdentifier;
|
||||
import org.whispersystems.signalservice.api.push.ServiceId;
|
||||
import org.whispersystems.signalservice.api.push.PNI;
|
||||
import org.whispersystems.signalservice.api.push.ServiceIdType;
|
||||
import org.whispersystems.signalservice.api.push.exceptions.PushNetworkException;
|
||||
|
||||
import java.io.IOException;
|
||||
|
@ -73,17 +73,17 @@ public class RotateSignedPreKeyJob extends BaseJob {
|
|||
return;
|
||||
}
|
||||
|
||||
rotate(aci, ApplicationDependencies.getProtocolStore().aci(), SignalStore.account().aciPreKeys());
|
||||
rotate(pni, ApplicationDependencies.getProtocolStore().pni(), SignalStore.account().pniPreKeys());
|
||||
rotate(ServiceIdType.ACI, ApplicationDependencies.getProtocolStore().aci(), SignalStore.account().aciPreKeys());
|
||||
rotate(ServiceIdType.PNI, ApplicationDependencies.getProtocolStore().pni(), SignalStore.account().pniPreKeys());
|
||||
}
|
||||
|
||||
private void rotate(@NonNull AccountIdentifier accountId, @NonNull SignalProtocolStore protocolStore, @NonNull PreKeyMetadataStore metadataStore)
|
||||
private void rotate(@NonNull ServiceIdType serviceIdType, @NonNull SignalProtocolStore protocolStore, @NonNull PreKeyMetadataStore metadataStore)
|
||||
throws IOException
|
||||
{
|
||||
SignalServiceAccountManager accountManager = ApplicationDependencies.getSignalServiceAccountManager();
|
||||
SignedPreKeyRecord signedPreKeyRecord = PreKeyUtil.generateAndStoreSignedPreKey(protocolStore, metadataStore, false);
|
||||
|
||||
accountManager.setSignedPreKey(accountId, signedPreKeyRecord);
|
||||
accountManager.setSignedPreKey(serviceIdType, signedPreKeyRecord);
|
||||
|
||||
metadataStore.setActiveSignedPreKeyId(signedPreKeyRecord.getId());
|
||||
metadataStore.setSignedPreKeyRegistered(true);
|
||||
|
|
|
@ -107,7 +107,7 @@ public final class SenderKeyDistributionSendJob extends BaseJob {
|
|||
List<SignalProtocolAddress> addresses = result.getSuccess()
|
||||
.getDevices()
|
||||
.stream()
|
||||
.map(device -> new SignalProtocolAddress(recipient.requireServiceId(), device))
|
||||
.map(device -> recipient.requireServiceId().toProtocolAddress(device))
|
||||
.collect(Collectors.toList());
|
||||
|
||||
ApplicationDependencies.getProtocolStore().aci().markSenderKeySharedWith(distributionId, addresses);
|
||||
|
|
|
@ -176,7 +176,7 @@ public class StorageSyncJob extends BaseJob {
|
|||
return;
|
||||
}
|
||||
|
||||
if (!Recipient.self().hasE164() || !Recipient.self().hasAci()) {
|
||||
if (!Recipient.self().hasE164() || !Recipient.self().hasServiceId()) {
|
||||
Log.w(TAG, "Missing E164 or ACI!");
|
||||
return;
|
||||
}
|
||||
|
|
|
@ -88,6 +88,11 @@ internal class AccountValues internal constructor(store: KeyValueStore) : Signal
|
|||
val aci: ACI?
|
||||
get() = ACI.parseOrNull(getString(KEY_ACI, null))
|
||||
|
||||
/** The local user's [ACI]. Will throw if not present. */
|
||||
fun requireAci(): ACI {
|
||||
return ACI.parseOrThrow(getString(KEY_ACI, null))
|
||||
}
|
||||
|
||||
fun setAci(aci: ACI) {
|
||||
putString(KEY_ACI, aci.toString())
|
||||
}
|
||||
|
@ -96,6 +101,11 @@ internal class AccountValues internal constructor(store: KeyValueStore) : Signal
|
|||
val pni: PNI?
|
||||
get() = PNI.parseOrNull(getString(KEY_PNI, null))
|
||||
|
||||
/** The local user's [PNI]. Will throw if not present. */
|
||||
fun requirePni(): PNI {
|
||||
return PNI.parseOrThrow(getString(KEY_PNI, null))
|
||||
}
|
||||
|
||||
fun setPni(pni: PNI) {
|
||||
putString(KEY_PNI, pni.toString())
|
||||
}
|
||||
|
|
|
@ -42,7 +42,6 @@ import org.whispersystems.signalservice.api.messages.calls.SignalServiceCallMess
|
|||
import org.whispersystems.signalservice.api.push.DistributionId;
|
||||
import org.whispersystems.signalservice.api.push.SignalServiceAddress;
|
||||
import org.whispersystems.signalservice.api.push.exceptions.NotFoundException;
|
||||
import org.whispersystems.signalservice.api.push.exceptions.UnregisteredUserException;
|
||||
import org.whispersystems.signalservice.internal.push.exceptions.InvalidUnidentifiedAccessHeaderException;
|
||||
import org.whispersystems.signalservice.internal.push.http.CancelationSignal;
|
||||
import org.whispersystems.signalservice.internal.push.http.PartialSendCompleteListener;
|
||||
|
@ -176,7 +175,7 @@ public final class GroupSendUtil {
|
|||
boolean validMembership = groupRecord.isPresent() && groupRecord.get().getMembers().contains(recipient.getId());
|
||||
|
||||
if (recipient.getSenderKeyCapability() == Recipient.Capability.SUPPORTED &&
|
||||
recipient.hasAci() &&
|
||||
recipient.hasServiceId() &&
|
||||
access.isPresent() &&
|
||||
access.get().getTargetUnidentifiedAccess().isPresent() &&
|
||||
validMembership)
|
||||
|
@ -311,8 +310,8 @@ public final class GroupSendUtil {
|
|||
Log.w(TAG, "There are " + unregisteredTargets.size() + " unregistered targets. Including failure results.");
|
||||
|
||||
List<SendMessageResult> unregisteredResults = unregisteredTargets.stream()
|
||||
.filter(Recipient::hasAci)
|
||||
.map(t -> SendMessageResult.unregisteredFailure(new SignalServiceAddress(t.requireAci(), t.getE164().orNull())))
|
||||
.filter(Recipient::hasServiceId)
|
||||
.map(t -> SendMessageResult.unregisteredFailure(new SignalServiceAddress(t.requireServiceId(), t.getE164().orNull())))
|
||||
.collect(Collectors.toList());
|
||||
|
||||
if (unregisteredResults.size() < unregisteredTargets.size()) {
|
||||
|
|
|
@ -652,7 +652,7 @@ public final class MessageContentProcessor {
|
|||
}
|
||||
|
||||
ApplicationDependencies.getSignalCallManager()
|
||||
.receivedOpaqueMessage(new WebRtcData.OpaqueMessageMetadata(senderRecipient.requireAci().uuid(),
|
||||
.receivedOpaqueMessage(new WebRtcData.OpaqueMessageMetadata(senderRecipient.requireServiceId().uuid(),
|
||||
message.getOpaque(),
|
||||
content.getSenderDevice(),
|
||||
messageAgeSeconds));
|
||||
|
@ -734,7 +734,7 @@ public final class MessageContentProcessor {
|
|||
long threadId = SignalDatabase.threads().getOrCreateThreadIdFor(recipient);
|
||||
|
||||
if (!recipient.isGroup()) {
|
||||
ApplicationDependencies.getProtocolStore().aci().deleteAllSessions(recipient.requireServiceId());
|
||||
ApplicationDependencies.getProtocolStore().aci().deleteAllSessions(recipient.requireServiceId().toString());
|
||||
|
||||
SecurityEvent.broadcastSecurityUpdateEvent(context);
|
||||
|
||||
|
@ -867,7 +867,7 @@ public final class MessageContentProcessor {
|
|||
return null;
|
||||
}
|
||||
|
||||
Recipient targetAuthor = Recipient.externalPush(context, reaction.getTargetAuthor());
|
||||
Recipient targetAuthor = Recipient.externalPush(reaction.getTargetAuthor());
|
||||
MessageRecord targetMessage = SignalDatabase.mmsSms().getMessageFor(reaction.getTargetSentTimestamp(), targetAuthor.getId());
|
||||
|
||||
if (targetMessage == null) {
|
||||
|
@ -1019,7 +1019,7 @@ public final class MessageContentProcessor {
|
|||
Recipient recipient;
|
||||
|
||||
if (response.getPerson().isPresent()) {
|
||||
recipient = Recipient.externalPush(context, response.getPerson().get());
|
||||
recipient = Recipient.externalPush(response.getPerson().get());
|
||||
} else if (response.getGroupId().isPresent()) {
|
||||
GroupId groupId = GroupId.v1(response.getGroupId().get());
|
||||
recipient = Recipient.externalPossiblyMigratedGroup(context, groupId);
|
||||
|
@ -1271,7 +1271,7 @@ public final class MessageContentProcessor {
|
|||
|
||||
List<Long> toMarkViewed = Stream.of(viewedMessages)
|
||||
.map(message -> {
|
||||
RecipientId author = Recipient.externalPush(context, message.getSender()).getId();
|
||||
RecipientId author = Recipient.externalPush(message.getSender()).getId();
|
||||
return SignalDatabase.mmsSms().getMessageFor(message.getTimestamp(), author);
|
||||
})
|
||||
.filter(message -> message != null && message.isMms())
|
||||
|
@ -1289,7 +1289,7 @@ public final class MessageContentProcessor {
|
|||
private void handleSynchronizeViewOnceOpenMessage(@NonNull ViewOnceOpenMessage openMessage, long envelopeTimestamp) {
|
||||
log(envelopeTimestamp, "Handling a view-once open for message: " + openMessage.getTimestamp());
|
||||
|
||||
RecipientId author = Recipient.externalPush(context, openMessage.getSender()).getId();
|
||||
RecipientId author = Recipient.externalPush(openMessage.getSender()).getId();
|
||||
long timestamp = openMessage.getTimestamp();
|
||||
MessageRecord record = SignalDatabase.mmsSms().getMessageFor(timestamp, author);
|
||||
|
||||
|
@ -1547,7 +1547,7 @@ public final class MessageContentProcessor {
|
|||
}
|
||||
|
||||
List<org.whispersystems.libsignal.util.Pair<RecipientId, Boolean>> unidentifiedStatus = Stream.of(members)
|
||||
.map(m -> new org.whispersystems.libsignal.util.Pair<>(m.getId(), message.isUnidentified(m.requireServiceId())))
|
||||
.map(m -> new org.whispersystems.libsignal.util.Pair<>(m.getId(), message.isUnidentified(m.requireServiceId().toString())))
|
||||
.toList();
|
||||
receiptDatabase.setUnidentified(unidentifiedStatus, messageId);
|
||||
}
|
||||
|
@ -1913,7 +1913,7 @@ public final class MessageContentProcessor {
|
|||
|
||||
warn(content.getTimestamp(), "[RetryReceipt] Received a retry receipt from " + formatSender(senderRecipient, content) + " for message with timestamp " + sentTimestamp + ".");
|
||||
|
||||
if (!senderRecipient.hasAci()) {
|
||||
if (!senderRecipient.hasServiceId()) {
|
||||
warn(content.getTimestamp(), "[RetryReceipt] Requester " + senderRecipient.getId() + " somehow has no UUID! timestamp: " + sentTimestamp);
|
||||
return;
|
||||
}
|
||||
|
@ -1953,7 +1953,7 @@ public final class MessageContentProcessor {
|
|||
|
||||
GroupId.V2 groupId = threadRecipient.requireGroupId().requireV2();
|
||||
DistributionId distributionId = SignalDatabase.groups().getOrCreateDistributionId(groupId);
|
||||
SignalProtocolAddress requesterAddress = new SignalProtocolAddress(requester.requireAci().toString(), content.getSenderDevice());
|
||||
SignalProtocolAddress requesterAddress = new SignalProtocolAddress(requester.requireServiceId().toString(), content.getSenderDevice());
|
||||
|
||||
SignalDatabase.senderKeyShared().delete(distributionId, Collections.singleton(requesterAddress));
|
||||
|
||||
|
@ -2030,7 +2030,7 @@ public final class MessageContentProcessor {
|
|||
}
|
||||
|
||||
public static boolean ratchetKeyMatches(@NonNull Recipient recipient, int deviceId, @NonNull ECPublicKey ratchetKey) {
|
||||
SignalProtocolAddress address = new SignalProtocolAddress(recipient.resolve().requireServiceId(), deviceId);
|
||||
SignalProtocolAddress address = recipient.resolve().requireServiceId().toProtocolAddress(deviceId);
|
||||
SessionRecord session = ApplicationDependencies.getProtocolStore().aci().loadSession(address);
|
||||
|
||||
return session.currentRatchetKeyMatches(ratchetKey);
|
||||
|
@ -2064,7 +2064,7 @@ public final class MessageContentProcessor {
|
|||
return Optional.absent();
|
||||
}
|
||||
|
||||
RecipientId author = Recipient.externalPush(context, quote.get().getAuthor()).getId();
|
||||
RecipientId author = Recipient.externalPush(quote.get().getAuthor()).getId();
|
||||
MessageRecord message = SignalDatabase.mmsSms().getMessageFor(quote.get().getId(), author);
|
||||
|
||||
if (message != null && !message.isRemoteDelete()) {
|
||||
|
@ -2200,7 +2200,7 @@ public final class MessageContentProcessor {
|
|||
List<Mention> mentions = new ArrayList<>(signalServiceMentions.size());
|
||||
|
||||
for (SignalServiceDataMessage.Mention mention : signalServiceMentions) {
|
||||
mentions.add(new Mention(Recipient.externalPush(context, mention.getAci(), null, false).getId(), mention.getStart(), mention.getLength()));
|
||||
mentions.add(new Mention(Recipient.externalPush(mention.getAci(), null, false).getId(), mention.getStart(), mention.getLength()));
|
||||
}
|
||||
|
||||
return mentions;
|
||||
|
@ -2223,7 +2223,7 @@ public final class MessageContentProcessor {
|
|||
private Recipient getSyncMessageDestination(@NonNull SentTranscriptMessage message)
|
||||
throws BadGroupIdException
|
||||
{
|
||||
return getGroupRecipient(message.getMessage().getGroupContext()).or(() -> Recipient.externalPush(context, message.getDestination().get()));
|
||||
return getGroupRecipient(message.getMessage().getGroupContext()).or(() -> Recipient.externalPush(message.getDestination().get()));
|
||||
}
|
||||
|
||||
private Recipient getMessageDestination(@NonNull SignalServiceContent content) throws BadGroupIdException {
|
||||
|
@ -2339,8 +2339,8 @@ public final class MessageContentProcessor {
|
|||
if (recipient.hasE164()) {
|
||||
unidentified |= message.isUnidentified(recipient.requireE164());
|
||||
}
|
||||
if (recipient.hasAci()) {
|
||||
unidentified |= message.isUnidentified(recipient.requireAci());
|
||||
if (recipient.hasServiceId()) {
|
||||
unidentified |= message.isUnidentified(recipient.requireServiceId());
|
||||
}
|
||||
|
||||
return unidentified;
|
||||
|
|
|
@ -44,7 +44,6 @@ import org.thoughtcrime.securesms.util.FeatureFlags;
|
|||
import org.thoughtcrime.securesms.util.GroupUtil;
|
||||
import org.whispersystems.libsignal.protocol.CiphertextMessage;
|
||||
import org.whispersystems.libsignal.protocol.DecryptionErrorMessage;
|
||||
import org.whispersystems.libsignal.state.SignalProtocolStore;
|
||||
import org.whispersystems.libsignal.util.guava.Optional;
|
||||
import org.whispersystems.signalservice.api.InvalidMessageStructureException;
|
||||
import org.whispersystems.signalservice.api.SignalServiceAccountDataStore;
|
||||
|
@ -78,7 +77,7 @@ public final class MessageDecryptionUtil {
|
|||
*/
|
||||
public static @NonNull DecryptionResult decrypt(@NonNull Context context, @NonNull SignalServiceEnvelope envelope) {
|
||||
SignalServiceAccountDataStore protocolStore = ApplicationDependencies.getProtocolStore().aci();
|
||||
SignalServiceAddress localAddress = new SignalServiceAddress(Recipient.self().requireAci(), Recipient.self().requireE164());
|
||||
SignalServiceAddress localAddress = new SignalServiceAddress(Recipient.self().requireServiceId(), Recipient.self().requireE164());
|
||||
SignalServiceCipher cipher = new SignalServiceCipher(localAddress, SignalStore.account().getDeviceId(), protocolStore, ReentrantSessionLock.INSTANCE, UnidentifiedAccessUtil.getCertificateValidator());
|
||||
List<Job> jobs = new LinkedList<>();
|
||||
|
||||
|
|
|
@ -17,6 +17,7 @@ import org.whispersystems.libsignal.state.SignalProtocolStore;
|
|||
import org.whispersystems.libsignal.state.SignedPreKeyRecord;
|
||||
import org.whispersystems.signalservice.api.SignalServiceAccountManager;
|
||||
import org.whispersystems.signalservice.api.push.PNI;
|
||||
import org.whispersystems.signalservice.api.push.ServiceIdType;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.List;
|
||||
|
@ -71,7 +72,7 @@ public class PniAccountInitializationMigrationJob extends MigrationJob {
|
|||
SignedPreKeyRecord signedPreKey = PreKeyUtil.generateAndStoreSignedPreKey(protocolStore, metadataStore, true);
|
||||
List<PreKeyRecord> oneTimePreKeys = PreKeyUtil.generateAndStoreOneTimePreKeys(protocolStore, metadataStore);
|
||||
|
||||
accountManager.setPreKeys(pni, protocolStore.getIdentityKeyPair().getPublicKey(), signedPreKey, oneTimePreKeys);
|
||||
accountManager.setPreKeys(ServiceIdType.PNI, protocolStore.getIdentityKeyPair().getPublicKey(), signedPreKey, oneTimePreKeys);
|
||||
metadataStore.setSignedPreKeyRegistered(true);
|
||||
}
|
||||
|
||||
|
|
|
@ -16,6 +16,7 @@ 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.ServiceId;
|
||||
import org.whispersystems.signalservice.api.util.UuidUtil;
|
||||
import org.whispersystems.signalservice.internal.push.SignalServiceProtos.GroupContext;
|
||||
import org.whispersystems.signalservice.internal.push.SignalServiceProtos.GroupContextV2;
|
||||
|
@ -191,7 +192,7 @@ public final class MessageGroupContext {
|
|||
List<RecipientId> members = new ArrayList<>(decryptedGroupV2Context.getGroupState().getMembersCount());
|
||||
|
||||
for (DecryptedMember member : decryptedGroupV2Context.getGroupState().getMembersList()) {
|
||||
RecipientId recipient = RecipientId.from(ACI.fromByteString(member.getUuid()), null);
|
||||
RecipientId recipient = RecipientId.from(ServiceId.fromByteString(member.getUuid()), null);
|
||||
if (!Recipient.self().getId().equals(recipient)) {
|
||||
members.add(recipient);
|
||||
}
|
||||
|
|
|
@ -7,8 +7,6 @@ import android.database.Cursor;
|
|||
import androidx.annotation.AnyThread;
|
||||
import androidx.annotation.NonNull;
|
||||
|
||||
import net.zetetic.database.sqlcipher.SQLiteDatabase;
|
||||
|
||||
import org.signal.core.util.ThreadUtil;
|
||||
import org.signal.core.util.concurrent.SignalExecutors;
|
||||
import org.signal.core.util.logging.Log;
|
||||
|
@ -153,7 +151,7 @@ public final class LiveRecipientCache {
|
|||
String localE164 = SignalStore.account().getE164();
|
||||
|
||||
if (localAci != null) {
|
||||
selfId = recipientDatabase.getByAci(localAci).or(recipientDatabase.getByE164(localE164)).orNull();
|
||||
selfId = recipientDatabase.getByServiceId(localAci).or(recipientDatabase.getByE164(localE164)).orNull();
|
||||
} else if (localE164 != null) {
|
||||
selfId = recipientDatabase.getByE164(localE164).orNull();
|
||||
} else {
|
||||
|
@ -235,6 +233,6 @@ public final class LiveRecipientCache {
|
|||
}
|
||||
|
||||
private boolean isValidForCache(@NonNull Recipient recipient) {
|
||||
return !recipient.getId().isUnknown() && (recipient.hasServiceIdentifier() || recipient.getGroupId().isPresent() || recipient.hasSmsAddress());
|
||||
return !recipient.getId().isUnknown() && (recipient.hasServiceId() || recipient.getGroupId().isPresent() || recipient.hasSmsAddress());
|
||||
}
|
||||
}
|
||||
|
|
|
@ -49,6 +49,7 @@ import org.thoughtcrime.securesms.wallpaper.ChatWallpaper;
|
|||
import org.whispersystems.libsignal.util.guava.Optional;
|
||||
import org.whispersystems.libsignal.util.guava.Preconditions;
|
||||
import org.whispersystems.signalservice.api.push.ACI;
|
||||
import org.whispersystems.signalservice.api.push.ServiceId;
|
||||
import org.whispersystems.signalservice.api.push.PNI;
|
||||
import org.whispersystems.signalservice.api.push.SignalServiceAddress;
|
||||
import org.whispersystems.signalservice.api.util.UuidUtil;
|
||||
|
@ -78,7 +79,7 @@ public class Recipient {
|
|||
|
||||
private final RecipientId id;
|
||||
private final boolean resolving;
|
||||
private final ACI aci;
|
||||
private final ServiceId serviceId;
|
||||
private final PNI pni;
|
||||
private final String username;
|
||||
private final String e164;
|
||||
|
@ -166,8 +167,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 ACI aci, @NonNull String username) {
|
||||
Recipient recipient = externalPush(context, aci, null, false);
|
||||
public static @NonNull Recipient externalUsername(@NonNull ServiceId serviceId, @NonNull String username) {
|
||||
Recipient recipient = externalPush(serviceId, null, false);
|
||||
SignalDatabase.recipients().setUsername(recipient.getId(), username);
|
||||
return recipient;
|
||||
}
|
||||
|
@ -175,11 +176,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, ACI, String, boolean)}
|
||||
* {@link #externalPush(ServiceId, String, boolean)}
|
||||
*/
|
||||
@WorkerThread
|
||||
public static @NonNull Recipient externalPush(@NonNull Context context, @NonNull SignalServiceAddress signalServiceAddress) {
|
||||
return externalPush(context, signalServiceAddress.getAci(), signalServiceAddress.getNumber().orNull(), false);
|
||||
public static @NonNull Recipient externalPush(@NonNull SignalServiceAddress signalServiceAddress) {
|
||||
return externalPush(signalServiceAddress.getServiceId(), signalServiceAddress.getNumber().orNull(), false);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -188,11 +189,11 @@ public class Recipient {
|
|||
* prioritize E164 addresses and not use the UUIDs if possible.
|
||||
*/
|
||||
@WorkerThread
|
||||
public static @NonNull Recipient externalGV1Member(@NonNull Context context, @NonNull SignalServiceAddress address) {
|
||||
public static @NonNull Recipient externalGV1Member(@NonNull SignalServiceAddress address) {
|
||||
if (address.getNumber().isPresent()) {
|
||||
return externalPush(context, null, address.getNumber().get(), false);
|
||||
return externalPush(null, address.getNumber().get(), false);
|
||||
} else {
|
||||
return externalPush(context, address.getAci(), null, false);
|
||||
return externalPush(address.getServiceId(), null, false);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -207,7 +208,7 @@ public class Recipient {
|
|||
*/
|
||||
@WorkerThread
|
||||
public static @NonNull Recipient externalHighTrustPush(@NonNull Context context, @NonNull SignalServiceAddress signalServiceAddress) {
|
||||
return externalPush(context, signalServiceAddress.getAci(), signalServiceAddress.getNumber().orNull(), true);
|
||||
return externalPush(signalServiceAddress.getServiceId(), signalServiceAddress.getNumber().orNull(), true);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -223,13 +224,13 @@ public class Recipient {
|
|||
* that can be trusted as accurate (like an envelope).
|
||||
*/
|
||||
@WorkerThread
|
||||
public static @NonNull Recipient externalPush(@NonNull Context context, @Nullable ACI aci, @Nullable String e164, boolean highTrust) {
|
||||
if (ACI.UNKNOWN.equals(aci)) {
|
||||
public static @NonNull Recipient externalPush(@Nullable ServiceId serviceId, @Nullable String e164, boolean highTrust) {
|
||||
if (ServiceId.UNKNOWN.equals(serviceId)) {
|
||||
throw new AssertionError();
|
||||
}
|
||||
|
||||
RecipientDatabase db = SignalDatabase.recipients();
|
||||
RecipientId recipientId = db.getAndPossiblyMerge(aci, e164, highTrust);
|
||||
RecipientId recipientId = db.getAndPossiblyMerge(serviceId, e164, highTrust);
|
||||
|
||||
Recipient resolved = resolved(recipientId);
|
||||
|
||||
|
@ -237,9 +238,9 @@ public class Recipient {
|
|||
Log.w(TAG, "Resolved " + recipientId + ", but got back a recipient with " + resolved.getId());
|
||||
}
|
||||
|
||||
if (highTrust && !resolved.isRegistered() && aci != null) {
|
||||
if (highTrust && !resolved.isRegistered() && serviceId != null) {
|
||||
Log.w(TAG, "External high-trust push was locally marked unregistered. Marking as registered.");
|
||||
db.markRegistered(recipientId, aci);
|
||||
db.markRegistered(recipientId, serviceId);
|
||||
} else if (highTrust && !resolved.isRegistered()) {
|
||||
Log.w(TAG, "External high-trust push was locally marked unregistered, but we don't have an ACI, so we can't do anything.", new Throwable());
|
||||
}
|
||||
|
@ -305,7 +306,7 @@ public class Recipient {
|
|||
* or serialized groupId.
|
||||
*
|
||||
* If the identifier is a UUID of a Signal user, prefer using
|
||||
* {@link #externalPush(Context, ACI, String, boolean)} or its overload, as this will let us associate
|
||||
* {@link #externalPush(ServiceId, String, boolean)} or its overload, as this will let us associate
|
||||
* the phone number with the recipient.
|
||||
*/
|
||||
@WorkerThread
|
||||
|
@ -317,7 +318,7 @@ public class Recipient {
|
|||
|
||||
if (UuidUtil.isUuid(identifier)) {
|
||||
ACI uuid = ACI.parseOrThrow(identifier);
|
||||
id = db.getOrInsertFromAci(uuid);
|
||||
id = db.getOrInsertFromServiceId(uuid);
|
||||
} else if (GroupId.isEncodedGroup(identifier)) {
|
||||
id = db.getOrInsertFromGroupId(GroupId.parseOrThrow(identifier));
|
||||
} else if (NumberUtil.isValidEmail(identifier)) {
|
||||
|
@ -337,7 +338,7 @@ public class Recipient {
|
|||
Recipient(@NonNull RecipientId id) {
|
||||
this.id = id;
|
||||
this.resolving = true;
|
||||
this.aci = null;
|
||||
this.serviceId = null;
|
||||
this.pni = null;
|
||||
this.username = null;
|
||||
this.e164 = null;
|
||||
|
@ -392,9 +393,9 @@ public class Recipient {
|
|||
|
||||
public Recipient(@NonNull RecipientId id, @NonNull RecipientDetails details, boolean resolved) {
|
||||
this.id = id;
|
||||
this.resolving = !resolved;
|
||||
this.aci = details.aci;
|
||||
this.pni = details.pni;
|
||||
this.resolving = !resolved;
|
||||
this.serviceId = details.serviceId;
|
||||
this.pni = details.pni;
|
||||
this.username = details.username;
|
||||
this.e164 = details.e164;
|
||||
this.email = details.email;
|
||||
|
@ -614,8 +615,8 @@ public class Recipient {
|
|||
return StringUtil.isolateBidi(name);
|
||||
}
|
||||
|
||||
public @NonNull Optional<ACI> getAci() {
|
||||
return Optional.fromNullable(aci);
|
||||
public @NonNull Optional<ServiceId> getServiceId() {
|
||||
return Optional.fromNullable(serviceId);
|
||||
}
|
||||
|
||||
public @NonNull Optional<PNI> getPni() {
|
||||
|
@ -646,16 +647,6 @@ public class Recipient {
|
|||
return Optional.fromNullable(e164).or(Optional.fromNullable(email));
|
||||
}
|
||||
|
||||
public @NonNull ACI requireAci() {
|
||||
ACI resolved = resolving ? resolve().aci : aci;
|
||||
|
||||
if (resolved == null) {
|
||||
throw new MissingAddressError(id);
|
||||
}
|
||||
|
||||
return resolved;
|
||||
}
|
||||
|
||||
public @NonNull PNI requirePni() {
|
||||
PNI resolved = resolving ? resolve().pni : pni;
|
||||
|
||||
|
@ -706,16 +697,12 @@ public class Recipient {
|
|||
return getE164().isPresent();
|
||||
}
|
||||
|
||||
public boolean hasAci() {
|
||||
return getAci().isPresent();
|
||||
public boolean hasServiceId() {
|
||||
return getServiceId().isPresent();
|
||||
}
|
||||
|
||||
public boolean hasPni() {
|
||||
return getPni().isPresent();
|
||||
}
|
||||
|
||||
public boolean isAciOnly() {
|
||||
return hasAci() && !hasSmsAddress();
|
||||
public boolean isServiceIdOnly() {
|
||||
return hasServiceId() && !hasSmsAddress();
|
||||
}
|
||||
|
||||
public @NonNull GroupId requireGroupId() {
|
||||
|
@ -728,36 +715,31 @@ public class Recipient {
|
|||
return resolved;
|
||||
}
|
||||
|
||||
public boolean hasServiceIdentifier() {
|
||||
return aci != null || e164 != null;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return A string identifier able to be used with the Signal service. Prefers ACI, and if not
|
||||
* available, will return an E164 number.
|
||||
* The {@link ServiceId} of the user if available, otherwise throw.
|
||||
*/
|
||||
public @NonNull String requireServiceId() {
|
||||
Recipient resolved = resolving ? resolve() : this;
|
||||
public @NonNull ServiceId requireServiceId() {
|
||||
ServiceId resolved = resolving ? resolve().serviceId : serviceId;
|
||||
|
||||
if (resolved.getAci().isPresent()) {
|
||||
return resolved.requireAci().toString();
|
||||
} else {
|
||||
return getE164().get();
|
||||
if (resolved == null) {
|
||||
throw new MissingAddressError(id);
|
||||
}
|
||||
|
||||
return resolved;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return A single string to represent the recipient, in order of precedence:
|
||||
*
|
||||
* Group ID > ACI > Phone > Email
|
||||
* Group ID > ServiceId > Phone > Email
|
||||
*/
|
||||
public @NonNull String requireStringId() {
|
||||
Recipient resolved = resolving ? resolve() : this;
|
||||
|
||||
if (resolved.isGroup()) {
|
||||
return resolved.requireGroupId().toString();
|
||||
} else if (resolved.getAci().isPresent()) {
|
||||
return resolved.requireAci().toString();
|
||||
} else if (resolved.getServiceId().isPresent()) {
|
||||
return resolved.requireServiceId().toString();
|
||||
}
|
||||
|
||||
return requireSmsAddress();
|
||||
|
@ -1214,7 +1196,7 @@ public class Recipient {
|
|||
profileSharing == other.profileSharing &&
|
||||
lastProfileFetch == other.lastProfileFetch &&
|
||||
forceSmsSelection == other.forceSmsSelection &&
|
||||
Objects.equals(aci, other.aci) &&
|
||||
Objects.equals(serviceId, other.serviceId) &&
|
||||
Objects.equals(username, other.username) &&
|
||||
Objects.equals(e164, other.e164) &&
|
||||
Objects.equals(email, other.email) &&
|
||||
|
|
|
@ -25,6 +25,7 @@ import org.thoughtcrime.securesms.wallpaper.ChatWallpaper;
|
|||
import org.whispersystems.libsignal.util.guava.Optional;
|
||||
import org.whispersystems.signalservice.api.push.ACI;
|
||||
import org.whispersystems.signalservice.api.push.PNI;
|
||||
import org.whispersystems.signalservice.api.push.ServiceId;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.LinkedList;
|
||||
|
@ -32,7 +33,7 @@ import java.util.List;
|
|||
|
||||
public class RecipientDetails {
|
||||
|
||||
final ACI aci;
|
||||
final ServiceId serviceId;
|
||||
final PNI pni;
|
||||
final String username;
|
||||
final String e164;
|
||||
|
@ -99,7 +100,7 @@ public class RecipientDetails {
|
|||
this.systemContactPhoto = Util.uri(record.getSystemContactPhotoUri());
|
||||
this.customLabel = record.getSystemPhoneLabel();
|
||||
this.contactUri = Util.uri(record.getSystemContactUri());
|
||||
this.aci = record.getAci();
|
||||
this.serviceId = record.getServiceId();
|
||||
this.pni = record.getPni();
|
||||
this.username = record.getUsername();
|
||||
this.e164 = record.getE164();
|
||||
|
@ -156,9 +157,9 @@ public class RecipientDetails {
|
|||
this.groupAvatarId = null;
|
||||
this.systemContactPhoto = null;
|
||||
this.customLabel = null;
|
||||
this.contactUri = null;
|
||||
this.aci = null;
|
||||
this.pni = null;
|
||||
this.contactUri = null;
|
||||
this.serviceId = null;
|
||||
this.pni = null;
|
||||
this.username = null;
|
||||
this.e164 = null;
|
||||
this.email = null;
|
||||
|
@ -210,7 +211,7 @@ public class RecipientDetails {
|
|||
public static @NonNull RecipientDetails forIndividual(@NonNull Context context, @NonNull RecipientRecord settings) {
|
||||
boolean systemContact = !settings.getSystemProfileName().isEmpty();
|
||||
boolean isSelf = (settings.getE164() != null && settings.getE164().equals(SignalStore.account().getE164())) ||
|
||||
(settings.getAci() != null && settings.getAci().equals(SignalStore.account().getAci()));
|
||||
(settings.getServiceId() != null && settings.getServiceId().equals(SignalStore.account().getAci()));
|
||||
boolean isReleaseChannel = settings.getId().equals(SignalStore.releaseChannelValues().getReleaseChannelRecipientId());
|
||||
|
||||
RegisteredState registeredState = settings.getRegistered();
|
||||
|
|
|
@ -15,13 +15,13 @@ 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.ServiceId;
|
||||
import org.whispersystems.signalservice.api.push.SignalServiceAddress;
|
||||
import org.whispersystems.signalservice.api.util.UuidUtil;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
import java.util.UUID;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
public class RecipientId implements Parcelable, Comparable<RecipientId> {
|
||||
|
@ -55,7 +55,7 @@ public class RecipientId implements Parcelable, Comparable<RecipientId> {
|
|||
|
||||
@AnyThread
|
||||
public static @NonNull RecipientId from(@NonNull SignalServiceAddress address) {
|
||||
return from(address.getAci(), address.getNumber().orNull(), false);
|
||||
return from(address.getServiceId(), address.getNumber().orNull(), false);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -78,7 +78,7 @@ public class RecipientId implements Parcelable, Comparable<RecipientId> {
|
|||
*/
|
||||
@AnyThread
|
||||
public static @NonNull RecipientId fromHighTrust(@NonNull SignalServiceAddress address) {
|
||||
return from(address.getAci(), address.getNumber().orNull(), true);
|
||||
return from(address.getServiceId(), address.getNumber().orNull(), true);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -86,17 +86,17 @@ public class RecipientId implements Parcelable, Comparable<RecipientId> {
|
|||
*/
|
||||
@AnyThread
|
||||
@SuppressLint("WrongThread")
|
||||
public static @NonNull RecipientId from(@Nullable ACI aci, @Nullable String e164) {
|
||||
public static @NonNull RecipientId from(@Nullable ServiceId aci, @Nullable String e164) {
|
||||
return from(aci, e164, false);
|
||||
}
|
||||
|
||||
@AnyThread
|
||||
@SuppressLint("WrongThread")
|
||||
private static @NonNull RecipientId from(@Nullable ACI aci, @Nullable String e164, boolean highTrust) {
|
||||
private static @NonNull RecipientId from(@Nullable ServiceId aci, @Nullable String e164, boolean highTrust) {
|
||||
RecipientId recipientId = RecipientIdCache.INSTANCE.get(aci, e164);
|
||||
|
||||
if (recipientId == null) {
|
||||
Recipient recipient = Recipient.externalPush(ApplicationDependencies.getApplication(), aci, e164, highTrust);
|
||||
Recipient recipient = Recipient.externalPush(aci, e164, highTrust);
|
||||
RecipientIdCache.INSTANCE.put(recipient);
|
||||
recipientId = recipient.getId();
|
||||
}
|
||||
|
|
|
@ -5,11 +5,10 @@ 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 org.whispersystems.signalservice.api.push.ServiceId;
|
||||
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.Map;
|
||||
import java.util.UUID;
|
||||
|
||||
/**
|
||||
* Thread safe cache that allows faster looking up of {@link RecipientId}s without hitting the database.
|
||||
|
@ -34,22 +33,22 @@ final class RecipientIdCache {
|
|||
}
|
||||
|
||||
synchronized void put(@NonNull Recipient recipient) {
|
||||
RecipientId recipientId = recipient.getId();
|
||||
Optional<String> e164 = recipient.getE164();
|
||||
Optional<ACI> aci = recipient.getAci();
|
||||
RecipientId recipientId = recipient.getId();
|
||||
Optional<String> e164 = recipient.getE164();
|
||||
Optional<ServiceId> serviceId = recipient.getServiceId();
|
||||
|
||||
if (e164.isPresent()) {
|
||||
ids.put(e164.get(), recipientId);
|
||||
}
|
||||
|
||||
if (aci.isPresent()) {
|
||||
ids.put(aci.get(), recipientId);
|
||||
if (serviceId.isPresent()) {
|
||||
ids.put(serviceId.get(), recipientId);
|
||||
}
|
||||
}
|
||||
|
||||
synchronized @Nullable RecipientId get(@Nullable ACI aci, @Nullable String e164) {
|
||||
if (aci != null && e164 != null) {
|
||||
RecipientId recipientIdByAci = ids.get(aci);
|
||||
synchronized @Nullable RecipientId get(@Nullable ServiceId serviceId, @Nullable String e164) {
|
||||
if (serviceId != null && e164 != null) {
|
||||
RecipientId recipientIdByAci = ids.get(serviceId);
|
||||
if (recipientIdByAci == null) return null;
|
||||
|
||||
RecipientId recipientIdByE164 = ids.get(e164);
|
||||
|
@ -58,13 +57,13 @@ final class RecipientIdCache {
|
|||
if (recipientIdByAci.equals(recipientIdByE164)) {
|
||||
return recipientIdByAci;
|
||||
} else {
|
||||
ids.remove(aci);
|
||||
ids.remove(serviceId);
|
||||
ids.remove(e164);
|
||||
Log.w(TAG, "Seen invalid RecipientIdCacheState");
|
||||
return null;
|
||||
}
|
||||
} else if (aci != null) {
|
||||
return ids.get(aci);
|
||||
} else if (serviceId != null) {
|
||||
return ids.get(serviceId);
|
||||
} else if (e164 != null) {
|
||||
return ids.get(e164);
|
||||
}
|
||||
|
|
|
@ -49,11 +49,11 @@ public class RecipientUtil {
|
|||
{
|
||||
recipient = recipient.resolve();
|
||||
|
||||
if (!recipient.getAci().isPresent() && !recipient.getE164().isPresent()) {
|
||||
if (!recipient.getServiceId().isPresent() && !recipient.getE164().isPresent()) {
|
||||
throw new AssertionError(recipient.getId() + " - No UUID or phone number!");
|
||||
}
|
||||
|
||||
if (!recipient.getAci().isPresent()) {
|
||||
if (!recipient.getServiceId().isPresent()) {
|
||||
Log.i(TAG, recipient.getId() + " is missing a UUID...");
|
||||
RegisteredState state = DirectoryHelper.refreshDirectoryFor(context, recipient, false);
|
||||
|
||||
|
@ -61,8 +61,8 @@ public class RecipientUtil {
|
|||
Log.i(TAG, "Successfully performed a UUID fetch for " + recipient.getId() + ". Registered: " + state);
|
||||
}
|
||||
|
||||
if (recipient.hasAci()) {
|
||||
return new SignalServiceAddress(recipient.requireAci(), Optional.fromNullable(recipient.resolve().getE164().orNull()));
|
||||
if (recipient.hasServiceId()) {
|
||||
return new SignalServiceAddress(recipient.requireServiceId(), Optional.fromNullable(recipient.resolve().getE164().orNull()));
|
||||
} else {
|
||||
throw new NotFoundException(recipient.getId() + " is not registered!");
|
||||
}
|
||||
|
@ -81,7 +81,7 @@ public class RecipientUtil {
|
|||
|
||||
return Stream.of(recipients)
|
||||
.map(Recipient::resolve)
|
||||
.map(r -> new SignalServiceAddress(r.requireAci(), r.getE164().orNull()))
|
||||
.map(r -> new SignalServiceAddress(r.requireServiceId(), r.getE164().orNull()))
|
||||
.toList();
|
||||
}
|
||||
|
||||
|
@ -93,7 +93,7 @@ public class RecipientUtil {
|
|||
{
|
||||
List<Recipient> recipientsWithoutUuids = Stream.of(recipients)
|
||||
.map(Recipient::resolve)
|
||||
.filterNot(Recipient::hasAci)
|
||||
.filterNot(Recipient::hasServiceId)
|
||||
.toList();
|
||||
|
||||
if (recipientsWithoutUuids.size() > 0) {
|
||||
|
@ -178,7 +178,7 @@ public class RecipientUtil {
|
|||
ApplicationDependencies.getJobManager().add(new MultiDeviceBlockedUpdateJob());
|
||||
StorageSyncHelper.scheduleSyncForDataChange();
|
||||
|
||||
if (recipient.hasServiceIdentifier()) {
|
||||
if (recipient.hasServiceId()) {
|
||||
ApplicationDependencies.getJobManager().add(MultiDeviceMessageRequestResponseJob.forAccept(recipient.getId()));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -37,8 +37,9 @@ 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.push.AccountIdentifier;
|
||||
import org.whispersystems.signalservice.api.push.ServiceId;
|
||||
import org.whispersystems.signalservice.api.push.PNI;
|
||||
import org.whispersystems.signalservice.api.push.ServiceIdType;
|
||||
import org.whispersystems.signalservice.api.push.SignalServiceAddress;
|
||||
import org.whispersystems.signalservice.internal.ServiceResponse;
|
||||
import org.whispersystems.signalservice.internal.push.VerifyAccountResponse;
|
||||
|
@ -142,15 +143,15 @@ public final class RegistrationRepository {
|
|||
SignalServiceAccountDataStoreImpl aciProtocolStore = ApplicationDependencies.getProtocolStore().aci();
|
||||
SignalServiceAccountDataStoreImpl pniProtocolStore = ApplicationDependencies.getProtocolStore().pni();
|
||||
|
||||
generateAndRegisterPreKeys(aci, accountManager, aciProtocolStore, SignalStore.account().aciPreKeys());
|
||||
generateAndRegisterPreKeys(pni, accountManager, pniProtocolStore, SignalStore.account().pniPreKeys());
|
||||
generateAndRegisterPreKeys(ServiceIdType.ACI, accountManager, aciProtocolStore, SignalStore.account().aciPreKeys());
|
||||
generateAndRegisterPreKeys(ServiceIdType.PNI, accountManager, pniProtocolStore, SignalStore.account().pniPreKeys());
|
||||
|
||||
if (registrationData.isFcm()) {
|
||||
accountManager.setGcmId(Optional.fromNullable(registrationData.getFcmToken()));
|
||||
}
|
||||
|
||||
RecipientDatabase recipientDatabase = SignalDatabase.recipients();
|
||||
RecipientId selfId = Recipient.externalPush(context, aci, registrationData.getE164(), true).getId();
|
||||
RecipientId selfId = Recipient.externalPush(aci, registrationData.getE164(), true).getId();
|
||||
|
||||
recipientDatabase.setProfileSharing(selfId, true);
|
||||
recipientDatabase.markRegisteredOrThrow(selfId, aci);
|
||||
|
@ -175,7 +176,7 @@ public final class RegistrationRepository {
|
|||
PinState.onRegistration(context, kbsData, pin, hasPin);
|
||||
}
|
||||
|
||||
private void generateAndRegisterPreKeys(@NonNull AccountIdentifier accountId,
|
||||
private void generateAndRegisterPreKeys(@NonNull ServiceIdType serviceIdType,
|
||||
@NonNull SignalServiceAccountManager accountManager,
|
||||
@NonNull SignalProtocolStore protocolStore,
|
||||
@NonNull PreKeyMetadataStore metadataStore)
|
||||
|
@ -184,7 +185,7 @@ public final class RegistrationRepository {
|
|||
SignedPreKeyRecord signedPreKey = PreKeyUtil.generateAndStoreSignedPreKey(protocolStore, metadataStore, true);
|
||||
List<PreKeyRecord> oneTimePreKeys = PreKeyUtil.generateAndStoreOneTimePreKeys(protocolStore, metadataStore);
|
||||
|
||||
accountManager.setPreKeys(accountId, protocolStore.getIdentityKeyPair().getPublicKey(), signedPreKey, oneTimePreKeys);
|
||||
accountManager.setPreKeys(serviceIdType, protocolStore.getIdentityKeyPair().getPublicKey(), signedPreKey, oneTimePreKeys);
|
||||
metadataStore.setSignedPreKeyRegistered(true);
|
||||
}
|
||||
|
||||
|
|
|
@ -83,7 +83,7 @@ public class GroupActionProcessor extends DeviceAwareActionProcessor {
|
|||
seen.add(Recipient.self());
|
||||
|
||||
for (GroupCall.RemoteDeviceState device : remoteDeviceStates) {
|
||||
Recipient recipient = Recipient.externalPush(context, ACI.from(device.getUserId()), null, false);
|
||||
Recipient recipient = Recipient.externalPush(ACI.from(device.getUserId()), null, false);
|
||||
CallParticipantId callParticipantId = new CallParticipantId(device.getDemuxId(), recipient.getId());
|
||||
CallParticipant callParticipant = participants.get(callParticipantId);
|
||||
|
||||
|
|
|
@ -123,8 +123,8 @@ public class GroupConnectedActionProcessor extends GroupActionProcessor {
|
|||
webRtcInteractor.sendGroupCallMessage(currentState.getCallInfoState().getCallRecipient(), eraId);
|
||||
|
||||
List<UUID> members = new ArrayList<>(peekInfo.getJoinedMembers());
|
||||
if (!members.contains(Recipient.self().requireAci().uuid())) {
|
||||
members.add(Recipient.self().requireAci().uuid());
|
||||
if (!members.contains(Recipient.self().requireServiceId().uuid())) {
|
||||
members.add(Recipient.self().requireServiceId().uuid());
|
||||
}
|
||||
webRtcInteractor.updateGroupCallUpdateMessage(currentState.getCallInfoState().getCallRecipient().getId(), eraId, members, WebRtcUtil.isCallFull(peekInfo));
|
||||
|
||||
|
@ -149,7 +149,7 @@ public class GroupConnectedActionProcessor extends GroupActionProcessor {
|
|||
String eraId = WebRtcUtil.getGroupCallEraId(groupCall);
|
||||
webRtcInteractor.sendGroupCallMessage(currentState.getCallInfoState().getCallRecipient(), eraId);
|
||||
|
||||
List<UUID> members = Stream.of(currentState.getCallInfoState().getRemoteCallParticipants()).map(p -> p.getRecipient().requireAci().uuid()).toList();
|
||||
List<UUID> members = Stream.of(currentState.getCallInfoState().getRemoteCallParticipants()).map(p -> p.getRecipient().requireServiceId().uuid()).toList();
|
||||
webRtcInteractor.updateGroupCallUpdateMessage(currentState.getCallInfoState().getCallRecipient().getId(), eraId, members, false);
|
||||
|
||||
currentState = currentState.builder()
|
||||
|
|
|
@ -114,7 +114,7 @@ public class GroupPreJoinActionProcessor extends GroupActionProcessor {
|
|||
}
|
||||
|
||||
List<Recipient> callParticipants = Stream.of(peekInfo.getJoinedMembers())
|
||||
.map(uuid -> Recipient.externalPush(context, ACI.from(uuid), null, false))
|
||||
.map(uuid -> Recipient.externalPush(ACI.from(uuid), null, false))
|
||||
.toList();
|
||||
|
||||
WebRtcServiceStateBuilder.CallInfoStateBuilder builder = currentState.builder()
|
||||
|
|
|
@ -138,7 +138,7 @@ public final class IncomingGroupCallActionProcessor extends DeviceAwareActionPro
|
|||
.changeCallSetupState(RemotePeer.GROUP_CALL_ID)
|
||||
.isRemoteVideoOffer(true)
|
||||
.ringId(ringId)
|
||||
.ringerRecipient(Recipient.externalPush(context, ACI.from(uuid), null, false))
|
||||
.ringerRecipient(Recipient.externalPush(ACI.from(uuid), null, false))
|
||||
.commit()
|
||||
.changeCallInfoState()
|
||||
.activePeer(new RemotePeer(currentState.getCallInfoState().getCallRecipient().getId(), RemotePeer.GROUP_CALL_ID))
|
||||
|
|
|
@ -154,7 +154,7 @@ public final class SignalCallManager implements CallManager.Observer, GroupCall.
|
|||
serviceExecutor.execute(() -> {
|
||||
if (needsToSetSelfUuid) {
|
||||
try {
|
||||
callManager.setSelfUuid(Recipient.self().requireAci().uuid());
|
||||
callManager.setSelfUuid(Recipient.self().requireServiceId().uuid());
|
||||
needsToSetSelfUuid = false;
|
||||
} catch (CallException e) {
|
||||
Log.w(TAG, "Unable to set self UUID on CallManager", e);
|
||||
|
|
|
@ -13,9 +13,9 @@ 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.ServiceId;
|
||||
import org.whispersystems.signalservice.api.push.SignalServiceAddress;
|
||||
import org.whispersystems.signalservice.api.storage.SignalContactRecord;
|
||||
import org.whispersystems.signalservice.api.util.UuidUtil;
|
||||
import org.whispersystems.signalservice.internal.storage.protos.ContactRecord.IdentityState;
|
||||
|
||||
import java.util.Arrays;
|
||||
|
@ -51,10 +51,10 @@ public class ContactRecordProcessor extends DefaultStorageRecordProcessor<Signal
|
|||
if (address == null) {
|
||||
Log.w(TAG, "No address on the ContentRecord -- marking as invalid.");
|
||||
return true;
|
||||
} else if (!address.hasValidAci()) {
|
||||
} else if (!address.hasValidServiceId()) {
|
||||
Log.w(TAG, "Found a ContactRecord without a UUID -- marking as invalid.");
|
||||
return true;
|
||||
} else if ((self.getAci().isPresent() && address.getAci().equals(self.requireAci())) ||
|
||||
} else if ((self.getServiceId().isPresent() && address.getServiceId().equals(self.requireServiceId())) ||
|
||||
(self.getE164().isPresent() && address.getNumber().equals(self.getE164())))
|
||||
{
|
||||
Log.w(TAG, "Found a ContactRecord for ourselves -- marking as invalid.");
|
||||
|
@ -67,7 +67,7 @@ public class ContactRecordProcessor extends DefaultStorageRecordProcessor<Signal
|
|||
@Override
|
||||
@NonNull Optional<SignalContactRecord> getMatching(@NonNull SignalContactRecord remote, @NonNull StorageKeyGenerator keyGenerator) {
|
||||
SignalServiceAddress address = remote.getAddress();
|
||||
Optional<RecipientId> byUuid = recipientDatabase.getByAci(address.getAci());
|
||||
Optional<RecipientId> byUuid = recipientDatabase.getByServiceId(address.getServiceId());
|
||||
Optional<RecipientId> byE164 = address.getNumber().isPresent() ? recipientDatabase.getByE164(address.getNumber().get()) : Optional.absent();
|
||||
|
||||
return byUuid.or(byE164).transform(recipientDatabase::getRecordForSync)
|
||||
|
@ -98,9 +98,9 @@ public class ContactRecordProcessor extends DefaultStorageRecordProcessor<Signal
|
|||
}
|
||||
|
||||
byte[] unknownFields = remote.serializeUnknownFields();
|
||||
ACI aci = local.getAddress().getAci() == ACI.UNKNOWN ? remote.getAddress().getAci() : local.getAddress().getAci();
|
||||
ServiceId serviceId = local.getAddress().getServiceId() == ServiceId.UNKNOWN ? remote.getAddress().getServiceId() : local.getAddress().getServiceId();
|
||||
String e164 = remote.getAddress().getNumber().or(local.getAddress().getNumber()).orNull();
|
||||
SignalServiceAddress address = new SignalServiceAddress(aci, e164);
|
||||
SignalServiceAddress address = new SignalServiceAddress(serviceId, e164);
|
||||
byte[] profileKey = remote.getProfileKey().or(local.getProfileKey()).orNull();
|
||||
String username = remote.getUsername().or(local.getUsername()).or("");
|
||||
IdentityState identityState = remote.getIdentityState();
|
||||
|
@ -146,7 +146,7 @@ public class ContactRecordProcessor extends DefaultStorageRecordProcessor<Signal
|
|||
|
||||
@Override
|
||||
public int compare(@NonNull SignalContactRecord lhs, @NonNull SignalContactRecord rhs) {
|
||||
if (Objects.equals(lhs.getAddress().getAci(), rhs.getAddress().getAci()) ||
|
||||
if (Objects.equals(lhs.getAddress().getServiceId(), rhs.getAddress().getServiceId()) ||
|
||||
Objects.equals(lhs.getAddress().getNumber(), rhs.getAddress().getNumber()))
|
||||
{
|
||||
return 0;
|
||||
|
|
|
@ -13,6 +13,7 @@ import org.thoughtcrime.securesms.groups.GroupId;
|
|||
import org.thoughtcrime.securesms.keyvalue.PhoneNumberPrivacyValues;
|
||||
import org.thoughtcrime.securesms.subscription.Subscriber;
|
||||
import org.whispersystems.signalservice.api.push.ACI;
|
||||
import org.whispersystems.signalservice.api.push.ServiceId;
|
||||
import org.whispersystems.signalservice.api.push.SignalServiceAddress;
|
||||
import org.whispersystems.signalservice.api.storage.SignalAccountRecord;
|
||||
import org.whispersystems.signalservice.api.storage.SignalContactRecord;
|
||||
|
@ -83,7 +84,7 @@ public final class StorageSyncModels {
|
|||
|
||||
private static @NonNull SignalAccountRecord.PinnedConversation localToRemotePinnedConversation(@NonNull RecipientRecord settings) {
|
||||
switch (settings.getGroupType()) {
|
||||
case NONE : return SignalAccountRecord.PinnedConversation.forContact(new SignalServiceAddress(settings.getAci(), settings.getE164()));
|
||||
case NONE : return SignalAccountRecord.PinnedConversation.forContact(new SignalServiceAddress(settings.getServiceId(), settings.getE164()));
|
||||
case SIGNAL_V1: return SignalAccountRecord.PinnedConversation.forGroupV1(settings.getGroupId().requireV1().getDecodedId());
|
||||
case SIGNAL_V2: return SignalAccountRecord.PinnedConversation.forGroupV2(settings.getSyncExtras().getGroupMasterKey().serialize());
|
||||
default : throw new AssertionError("Unexpected group type!");
|
||||
|
@ -91,13 +92,13 @@ public final class StorageSyncModels {
|
|||
}
|
||||
|
||||
private static @NonNull SignalContactRecord localToRemoteContact(@NonNull RecipientRecord recipient, byte[] rawStorageId) {
|
||||
if (recipient.getAci() == null && recipient.getE164() == null) {
|
||||
if (recipient.getServiceId() == null && recipient.getE164() == null) {
|
||||
throw new AssertionError("Must have either a UUID or a phone number!");
|
||||
}
|
||||
|
||||
ACI aci = recipient.getAci() != null ? recipient.getAci() : ACI.UNKNOWN;
|
||||
ServiceId serviceId = recipient.getServiceId() != null ? recipient.getServiceId() : ServiceId.UNKNOWN;
|
||||
|
||||
return new SignalContactRecord.Builder(rawStorageId, new SignalServiceAddress(aci, recipient.getE164()), recipient.getSyncExtras().getStorageProto())
|
||||
return new SignalContactRecord.Builder(rawStorageId, new SignalServiceAddress(serviceId, recipient.getE164()), recipient.getSyncExtras().getStorageProto())
|
||||
.setProfileKey(recipient.getProfileKey())
|
||||
.setGivenName(recipient.getProfileName().getGivenName())
|
||||
.setFamilyName(recipient.getProfileName().getFamilyName())
|
||||
|
|
|
@ -142,7 +142,7 @@ public final class StorageSyncValidations {
|
|||
|
||||
if (insert.getContact().isPresent()) {
|
||||
SignalServiceAddress address = insert.getContact().get().getAddress();
|
||||
if (self.requireE164().equals(address.getNumber().or("")) || self.requireAci().equals(address.getAci())) {
|
||||
if (self.requireE164().equals(address.getNumber().or("")) || self.requireServiceId().equals(address.getServiceId())) {
|
||||
throw new SelfAddedAsContactError();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -23,7 +23,7 @@ public final class BucketingUtil {
|
|||
* Calculate a user bucket for a given feature flag, uuid, and part per modulus.
|
||||
*
|
||||
* @param key Feature flag key (e.g., "research.megaphone.1")
|
||||
* @param uuid Current user's UUID (see {@link Recipient#getAci()})
|
||||
* @param uuid Current user's UUID (see {@link Recipient#getServiceId()})
|
||||
* @param modulus Drives the bucketing parts per N (e.g., passing 1,000,000 indicates bucketing into parts per million)
|
||||
*/
|
||||
public static long bucket(@NonNull String key, @NonNull UUID uuid, long modulus) {
|
||||
|
|
|
@ -240,7 +240,7 @@ public class CommunicationActions {
|
|||
SimpleTask.run(() -> {
|
||||
Recipient recipient = Recipient.external(activity, e164);
|
||||
|
||||
if (!recipient.isRegistered() || !recipient.hasAci()) {
|
||||
if (!recipient.isRegistered() || !recipient.hasServiceId()) {
|
||||
try {
|
||||
DirectoryHelper.refreshDirectoryFor(activity, recipient, false);
|
||||
recipient = Recipient.resolved(recipient.getId());
|
||||
|
|
|
@ -161,7 +161,7 @@ public final class IdentityUtil {
|
|||
public static void processVerifiedMessage(Context context, VerifiedMessage verifiedMessage) {
|
||||
try(SignalSessionLock.Lock unused = ReentrantSessionLock.INSTANCE.acquire()) {
|
||||
SignalIdentityKeyStore identityStore = ApplicationDependencies.getProtocolStore().aci().identities();
|
||||
Recipient recipient = Recipient.externalPush(context, verifiedMessage.getDestination());
|
||||
Recipient recipient = Recipient.externalPush(verifiedMessage.getDestination());
|
||||
Optional<IdentityRecord> identityRecord = identityStore.getIdentityRecord(recipient.getId());
|
||||
|
||||
if (!identityRecord.isPresent() && verifiedMessage.getVerified() == VerifiedMessage.VerifiedState.DEFAULT) {
|
||||
|
|
|
@ -76,12 +76,12 @@ public final class LocaleFeatureFlags {
|
|||
Map<String, Integer> countryCodeValues = parseCountryValues(serialized, 0);
|
||||
Recipient self = Recipient.self();
|
||||
|
||||
if (countryCodeValues.isEmpty() || !self.getE164().isPresent() || !self.getAci().isPresent()) {
|
||||
if (countryCodeValues.isEmpty() || !self.getE164().isPresent() || !self.getServiceId().isPresent()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
long countEnabled = getCountryValue(countryCodeValues, self.getE164().or(""), 0);
|
||||
long currentUserBucket = BucketingUtil.bucket(flag, self.requireAci().uuid(), 1_000_000);
|
||||
long currentUserBucket = BucketingUtil.bucket(flag, self.requireServiceId().uuid(), 1_000_000);
|
||||
|
||||
return countEnabled > currentUserBucket;
|
||||
}
|
||||
|
|
|
@ -10,7 +10,6 @@ import org.signal.core.util.logging.Log;
|
|||
import org.signal.zkgroup.InvalidInputException;
|
||||
import org.signal.zkgroup.profiles.ProfileKey;
|
||||
import org.thoughtcrime.securesms.badges.models.Badge;
|
||||
import org.thoughtcrime.securesms.crypto.IdentityKeyUtil;
|
||||
import org.thoughtcrime.securesms.crypto.ProfileKeyUtil;
|
||||
import org.thoughtcrime.securesms.crypto.UnidentifiedAccessUtil;
|
||||
import org.thoughtcrime.securesms.database.RecipientDatabase;
|
||||
|
@ -284,7 +283,7 @@ public final class ProfileUtil {
|
|||
|
||||
ProfileKey profileKey = ProfileKeyUtil.getSelfProfileKey();
|
||||
SignalServiceAccountManager accountManager = ApplicationDependencies.getSignalServiceAccountManager();
|
||||
String avatarPath = accountManager.setVersionedProfile(Recipient.self().requireAci(),
|
||||
String avatarPath = accountManager.setVersionedProfile(SignalStore.account().requireAci(),
|
||||
profileKey,
|
||||
profileName.serialize(),
|
||||
about,
|
||||
|
@ -321,8 +320,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.hasAci()) {
|
||||
return new SignalServiceAddress(recipient.requireAci(), recipient.getE164().orNull());
|
||||
if (recipient.hasServiceId()) {
|
||||
return new SignalServiceAddress(recipient.requireServiceId(), recipient.getE164().orNull());
|
||||
} else {
|
||||
throw new IOException(recipient.getId() + " not registered!");
|
||||
}
|
||||
|
|
|
@ -2,7 +2,7 @@ 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.ServiceId
|
||||
import org.whispersystems.signalservice.api.push.SignalServiceAddress
|
||||
|
||||
/**
|
||||
|
@ -11,10 +11,10 @@ import org.whispersystems.signalservice.api.push.SignalServiceAddress
|
|||
*/
|
||||
class RecipientAccessList(private val recipients: List<Recipient>) : List<Recipient> by recipients {
|
||||
|
||||
private val byAci: Map<ACI, Recipient> by lazy {
|
||||
private val byServiceId: Map<ServiceId, Recipient> by lazy {
|
||||
recipients
|
||||
.filter { it.hasAci() }
|
||||
.associateBy { it.requireAci() }
|
||||
.filter { it.hasServiceId() }
|
||||
.associateBy { it.requireServiceId() }
|
||||
}
|
||||
|
||||
private val byE164: Map<String, Recipient> by lazy {
|
||||
|
@ -24,8 +24,8 @@ class RecipientAccessList(private val recipients: List<Recipient>) : List<Recipi
|
|||
}
|
||||
|
||||
fun requireByAddress(address: SignalServiceAddress): Recipient {
|
||||
if (byAci.containsKey(address.aci)) {
|
||||
return byAci[address.aci]!!
|
||||
if (byServiceId.containsKey(address.serviceId)) {
|
||||
return byServiceId[address.serviceId]!!
|
||||
} else if (address.number.isPresent && byE164.containsKey(address.number.get())) {
|
||||
return byE164[address.number.get()]!!
|
||||
} else {
|
||||
|
|
|
@ -15,6 +15,7 @@ import org.thoughtcrime.securesms.recipients.RecipientId;
|
|||
import org.whispersystems.libsignal.util.guava.Optional;
|
||||
import org.whispersystems.signalservice.api.profiles.SignalServiceProfile;
|
||||
import org.whispersystems.signalservice.api.push.ACI;
|
||||
import org.whispersystems.signalservice.api.push.ServiceId;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.Locale;
|
||||
|
@ -51,15 +52,15 @@ public class UsernameUtil {
|
|||
}
|
||||
|
||||
@WorkerThread
|
||||
public static @NonNull Optional<ACI> fetchAciForUsername(@NonNull Context context, @NonNull String username) {
|
||||
public static @NonNull Optional<ServiceId> fetchAciForUsername(@NonNull String username) {
|
||||
Optional<RecipientId> localId = SignalDatabase.recipients().getByUsername(username);
|
||||
|
||||
if (localId.isPresent()) {
|
||||
Recipient recipient = Recipient.resolved(localId.get());
|
||||
|
||||
if (recipient.getAci().isPresent()) {
|
||||
if (recipient.getServiceId().isPresent()) {
|
||||
Log.i(TAG, "Found username locally -- using associated UUID.");
|
||||
return recipient.getAci();
|
||||
return recipient.getServiceId();
|
||||
} else {
|
||||
Log.w(TAG, "Found username locally, but it had no associated UUID! Clearing it.");
|
||||
SignalDatabase.recipients().clearUsernameIfExists(username);
|
||||
|
|
|
@ -16,7 +16,6 @@ import android.text.TextUtils;
|
|||
import android.text.method.LinkMovementMethod;
|
||||
import android.view.ContextMenu;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.Menu;
|
||||
import android.view.MenuInflater;
|
||||
import android.view.MenuItem;
|
||||
import android.view.View;
|
||||
|
@ -35,7 +34,6 @@ import android.widget.Toast;
|
|||
import androidx.annotation.DrawableRes;
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
import androidx.appcompat.app.AppCompatActivity;
|
||||
import androidx.appcompat.widget.Toolbar;
|
||||
import androidx.fragment.app.Fragment;
|
||||
import androidx.interpolator.view.animation.FastOutSlowInInterpolator;
|
||||
|
@ -212,18 +210,18 @@ public class VerifyDisplayFragment extends Fragment implements ViewTreeObserver.
|
|||
//noinspection WrongThread
|
||||
Recipient resolved = recipient.resolve();
|
||||
|
||||
if (FeatureFlags.verifyV2() && resolved.getAci().isPresent()) {
|
||||
if (FeatureFlags.verifyV2() && resolved.getServiceId().isPresent()) {
|
||||
Log.i(TAG, "Using UUID (version 2).");
|
||||
version = 2;
|
||||
localId = Recipient.self().requireAci().toByteArray();
|
||||
remoteId = resolved.requireAci().toByteArray();
|
||||
localId = Recipient.self().requireServiceId().toByteArray();
|
||||
remoteId = resolved.requireServiceId().toByteArray();
|
||||
} else if (!FeatureFlags.verifyV2() && resolved.getE164().isPresent()) {
|
||||
Log.i(TAG, "Using E164 (version 1).");
|
||||
version = 1;
|
||||
localId = Recipient.self().requireE164().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.getAci().isPresent(), resolved.getE164().isPresent()));
|
||||
Log.w(TAG, String.format(Locale.ENGLISH, "Could not show proper verification! verifyV2: %s, hasUuid: %s, hasE164: %s", FeatureFlags.verifyV2(), resolved.getServiceId().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())
|
||||
|
|
|
@ -26,6 +26,7 @@ import org.signal.storageservice.protos.groups.local.DecryptedMember;
|
|||
import org.signal.storageservice.protos.groups.local.DecryptedPendingMember;
|
||||
import org.thoughtcrime.securesms.testutil.MainThreadUtil;
|
||||
import org.whispersystems.signalservice.api.push.ACI;
|
||||
import org.whispersystems.signalservice.api.push.ServiceId;
|
||||
import org.whispersystems.signalservice.api.util.UuidUtil;
|
||||
|
||||
import java.util.Arrays;
|
||||
|
@ -1351,14 +1352,14 @@ public final class GroupsV2UpdateMessageProducerTest {
|
|||
}
|
||||
|
||||
private void assertSingleChangeMentioning(DecryptedGroupChange change, List<UUID> expectedMentions) {
|
||||
List<ACI> expectedMentionAcis = expectedMentions.stream().map(ACI::from).collect(Collectors.toList());
|
||||
List<ServiceId> expectedMentionSids = expectedMentions.stream().map(ServiceId::from).collect(Collectors.toList());
|
||||
|
||||
List<UpdateDescription> changes = producer.describeChanges(null, change);
|
||||
|
||||
assertThat(changes.size(), is(1));
|
||||
|
||||
UpdateDescription description = changes.get(0);
|
||||
assertThat(description.getMentioned(), is(expectedMentionAcis));
|
||||
assertThat(description.getMentioned(), is(expectedMentionSids));
|
||||
|
||||
if (expectedMentions.isEmpty()) {
|
||||
assertTrue(description.isStringStatic());
|
||||
|
@ -1397,8 +1398,8 @@ public final class GroupsV2UpdateMessageProducerTest {
|
|||
}
|
||||
|
||||
private static @NonNull GroupsV2UpdateMessageProducer.DescribeMemberStrategy createDescriber(@NonNull Map<UUID, String> map) {
|
||||
return aci -> {
|
||||
String name = map.get(aci.uuid());
|
||||
return serviceId -> {
|
||||
String name = map.get(serviceId.uuid());
|
||||
assertNotNull(name);
|
||||
return name;
|
||||
};
|
||||
|
|
|
@ -266,7 +266,7 @@ public final class RecipientIdCacheTest {
|
|||
Recipient mock = mock(Recipient.class);
|
||||
|
||||
when(mock.getId()).thenReturn(recipientId);
|
||||
when(mock.getAci()).thenReturn(Optional.fromNullable(aci));
|
||||
when(mock.getServiceId()).thenReturn(Optional.fromNullable(aci));
|
||||
when(mock.getE164()).thenReturn(Optional.fromNullable(e164));
|
||||
|
||||
return mock;
|
||||
|
|
|
@ -27,10 +27,8 @@ import org.whispersystems.signalservice.api.storage.StorageId;
|
|||
|
||||
import java.util.Arrays;
|
||||
import java.util.HashMap;
|
||||
import java.util.LinkedHashSet;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
import static junit.framework.TestCase.assertTrue;
|
||||
import static org.junit.Assert.assertEquals;
|
||||
|
@ -57,7 +55,7 @@ public final class StorageSyncHelperTest {
|
|||
|
||||
private static final Recipient SELF = mock(Recipient.class);
|
||||
static {
|
||||
when(SELF.getAci()).thenReturn(Optional.of(ACI_SELF));
|
||||
when(SELF.getServiceId()).thenReturn(Optional.of(ACI_SELF));
|
||||
when(SELF.getE164()).thenReturn(Optional.of(E164_SELF));
|
||||
when(SELF.resolve()).thenReturn(SELF);
|
||||
}
|
||||
|
|
|
@ -35,8 +35,9 @@ 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.AccountIdentifier;
|
||||
import org.whispersystems.signalservice.api.push.ServiceId;
|
||||
import org.whispersystems.signalservice.api.push.PNI;
|
||||
import org.whispersystems.signalservice.api.push.ServiceIdType;
|
||||
import org.whispersystems.signalservice.api.push.SignedPreKeyEntity;
|
||||
import org.whispersystems.signalservice.api.push.exceptions.NoContentException;
|
||||
import org.whispersystems.signalservice.api.push.exceptions.NonSuccessfulResponseCodeException;
|
||||
|
@ -420,18 +421,18 @@ public class SignalServiceAccountManager {
|
|||
*
|
||||
* @throws IOException
|
||||
*/
|
||||
public void setPreKeys(AccountIdentifier accountId, IdentityKey identityKey, SignedPreKeyRecord signedPreKey, List<PreKeyRecord> oneTimePreKeys)
|
||||
public void setPreKeys(ServiceIdType serviceIdType, IdentityKey identityKey, SignedPreKeyRecord signedPreKey, List<PreKeyRecord> oneTimePreKeys)
|
||||
throws IOException
|
||||
{
|
||||
this.pushServiceSocket.registerPreKeys(accountId, identityKey, signedPreKey, oneTimePreKeys);
|
||||
this.pushServiceSocket.registerPreKeys(serviceIdType, identityKey, signedPreKey, oneTimePreKeys);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return The server's count of currently available (eg. unused) prekeys for this user.
|
||||
* @throws IOException
|
||||
*/
|
||||
public int getPreKeysCount(AccountIdentifier accountId) throws IOException {
|
||||
return this.pushServiceSocket.getAvailablePreKeys(accountId);
|
||||
public int getPreKeysCount(ServiceIdType serviceIdType) throws IOException {
|
||||
return this.pushServiceSocket.getAvailablePreKeys(serviceIdType);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -440,22 +441,22 @@ public class SignalServiceAccountManager {
|
|||
* @param signedPreKey The client's new signed prekey.
|
||||
* @throws IOException
|
||||
*/
|
||||
public void setSignedPreKey(AccountIdentifier accountId, SignedPreKeyRecord signedPreKey) throws IOException {
|
||||
this.pushServiceSocket.setCurrentSignedPreKey(accountId, signedPreKey);
|
||||
public void setSignedPreKey(ServiceIdType serviceIdType, SignedPreKeyRecord signedPreKey) throws IOException {
|
||||
this.pushServiceSocket.setCurrentSignedPreKey(serviceIdType, signedPreKey);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return The server's view of the client's current signed prekey.
|
||||
* @throws IOException
|
||||
*/
|
||||
public SignedPreKeyEntity getSignedPreKey(AccountIdentifier accountId) throws IOException {
|
||||
return this.pushServiceSocket.getCurrentSignedPreKey(accountId);
|
||||
public SignedPreKeyEntity getSignedPreKey(ServiceIdType serviceIdType) throws IOException {
|
||||
return this.pushServiceSocket.getCurrentSignedPreKey(serviceIdType);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return True if the identifier corresponds to a registered user, otherwise false.
|
||||
*/
|
||||
public boolean isIdentifierRegistered(AccountIdentifier identifier) throws IOException {
|
||||
public boolean isIdentifierRegistered(ServiceId identifier) throws IOException {
|
||||
return pushServiceSocket.isIdentifierRegistered(identifier);
|
||||
}
|
||||
|
||||
|
@ -815,11 +816,11 @@ public class SignalServiceAccountManager {
|
|||
profileAvatarData);
|
||||
}
|
||||
|
||||
public Optional<ProfileKeyCredential> resolveProfileKeyCredential(ACI aci, ProfileKey profileKey, Locale locale)
|
||||
public Optional<ProfileKeyCredential> resolveProfileKeyCredential(ServiceId serviceId, ProfileKey profileKey, Locale locale)
|
||||
throws NonSuccessfulResponseCodeException, PushNetworkException
|
||||
{
|
||||
try {
|
||||
ProfileAndCredential credential = this.pushServiceSocket.retrieveVersionedProfileAndCredential(aci.uuid(), profileKey, Optional.absent(), locale).get(10, TimeUnit.SECONDS);
|
||||
ProfileAndCredential credential = this.pushServiceSocket.retrieveVersionedProfileAndCredential(serviceId.uuid(), profileKey, Optional.absent(), locale).get(10, TimeUnit.SECONDS);
|
||||
return credential.getProfileKeyCredential();
|
||||
} catch (InterruptedException | TimeoutException e) {
|
||||
throw new PushNetworkException(e);
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
package org.whispersystems.signalservice.api;
|
||||
|
||||
import org.whispersystems.signalservice.api.push.AccountIdentifier;
|
||||
import org.whispersystems.signalservice.api.push.ServiceId;
|
||||
|
||||
/**
|
||||
* And extension of the normal protocol store interface that has additional methods that are needed
|
||||
|
@ -11,7 +11,7 @@ public interface SignalServiceDataStore {
|
|||
/**
|
||||
* @return A {@link SignalServiceAccountDataStore} for the specified account.
|
||||
*/
|
||||
SignalServiceAccountDataStore get(AccountIdentifier accountIdentifier);
|
||||
SignalServiceAccountDataStore get(ServiceId accountIdentifier);
|
||||
|
||||
/**
|
||||
* @return A {@link SignalServiceAccountDataStore} for the ACI account.
|
||||
|
|
|
@ -21,10 +21,10 @@ import org.whispersystems.signalservice.api.messages.SignalServiceStickerManifes
|
|||
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.ServiceId;
|
||||
import org.whispersystems.signalservice.api.push.SignalServiceAddress;
|
||||
import org.whispersystems.signalservice.api.push.exceptions.MissingConfigurationException;
|
||||
import org.whispersystems.signalservice.api.util.CredentialsProvider;
|
||||
import org.whispersystems.signalservice.api.util.UuidUtil;
|
||||
import org.whispersystems.signalservice.internal.configuration.SignalServiceConfiguration;
|
||||
import org.whispersystems.signalservice.internal.push.PushServiceSocket;
|
||||
import org.whispersystems.signalservice.internal.push.SignalServiceEnvelopeEntity;
|
||||
|
@ -43,7 +43,6 @@ import java.util.ArrayList;
|
|||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
import java.util.UUID;
|
||||
|
||||
/**
|
||||
* The primary interface for receiving Signal Service messages.
|
||||
|
@ -91,13 +90,13 @@ public class SignalServiceMessageReceiver {
|
|||
SignalServiceProfile.RequestType requestType,
|
||||
Locale locale)
|
||||
{
|
||||
ACI aci = address.getAci();
|
||||
ServiceId serviceId = address.getServiceId();
|
||||
|
||||
if (profileKey.isPresent()) {
|
||||
if (requestType == SignalServiceProfile.RequestType.PROFILE_AND_CREDENTIAL) {
|
||||
return socket.retrieveVersionedProfileAndCredential(aci.uuid(), profileKey.get(), unidentifiedAccess, locale);
|
||||
return socket.retrieveVersionedProfileAndCredential(serviceId.uuid(), profileKey.get(), unidentifiedAccess, locale);
|
||||
} else {
|
||||
return FutureTransformers.map(socket.retrieveVersionedProfile(aci.uuid(), profileKey.get(), unidentifiedAccess, locale), profile -> {
|
||||
return FutureTransformers.map(socket.retrieveVersionedProfile(serviceId.uuid(), profileKey.get(), unidentifiedAccess, locale), profile -> {
|
||||
return new ProfileAndCredential(profile,
|
||||
SignalServiceProfile.RequestType.PROFILE,
|
||||
Optional.absent());
|
||||
|
|
|
@ -64,6 +64,7 @@ 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.ServiceId;
|
||||
import org.whispersystems.signalservice.api.push.SignalServiceAddress;
|
||||
import org.whispersystems.signalservice.api.push.exceptions.AuthorizationFailedException;
|
||||
import org.whispersystems.signalservice.api.push.exceptions.MalformedResponseException;
|
||||
|
@ -118,7 +119,6 @@ import org.whispersystems.signalservice.internal.push.http.ResumableUploadSpec;
|
|||
import org.whispersystems.signalservice.internal.util.Util;
|
||||
import org.whispersystems.util.Base64;
|
||||
import org.whispersystems.util.ByteArrayUtil;
|
||||
import org.whispersystems.util.FlagUtil;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
|
@ -795,7 +795,7 @@ 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().getAci().toString());
|
||||
.setAuthorUuid(message.getQuote().get().getAuthor().getServiceId().toString());
|
||||
|
||||
if (!message.getQuote().get().getMentions().isEmpty()) {
|
||||
for (SignalServiceDataMessage.Mention mention : message.getQuote().get().getMentions()) {
|
||||
|
@ -891,7 +891,7 @@ public class SignalServiceMessageSender {
|
|||
.setEmoji(message.getReaction().get().getEmoji())
|
||||
.setRemove(message.getReaction().get().isRemove())
|
||||
.setTargetSentTimestamp(message.getReaction().get().getTargetSentTimestamp())
|
||||
.setTargetAuthorUuid(message.getReaction().get().getTargetAuthor().getAci().toString());
|
||||
.setTargetAuthorUuid(message.getReaction().get().getTargetAuthor().getServiceId().toString());
|
||||
|
||||
builder.setReaction(reactionBuilder.build());
|
||||
builder.setRequiredProtocolVersion(Math.max(DataMessage.ProtocolVersion.REACTIONS_VALUE, builder.getRequiredProtocolVersion()));
|
||||
|
@ -1071,7 +1071,7 @@ public class SignalServiceMessageSender {
|
|||
if (result.getSuccess() != null) {
|
||||
SyncMessage.Sent.UnidentifiedDeliveryStatus.Builder builder = SyncMessage.Sent.UnidentifiedDeliveryStatus.newBuilder();
|
||||
|
||||
builder.setDestinationUuid(result.getAddress().getAci().toString());
|
||||
builder.setDestinationUuid(result.getAddress().getServiceId().toString());
|
||||
|
||||
if (result.getAddress().getNumber().isPresent()) {
|
||||
builder.setDestinationE164(result.getAddress().getNumber().get());
|
||||
|
@ -1084,7 +1084,7 @@ public class SignalServiceMessageSender {
|
|||
}
|
||||
|
||||
if (recipient.isPresent()) {
|
||||
sentMessage.setDestinationUuid(recipient.get().getAci().toString());
|
||||
sentMessage.setDestinationUuid(recipient.get().getServiceId().toString());
|
||||
|
||||
if (recipient.get().getNumber().isPresent()) {
|
||||
sentMessage.setDestinationE164(recipient.get().getNumber().get());
|
||||
|
@ -1112,7 +1112,7 @@ public class SignalServiceMessageSender {
|
|||
for (ReadMessage readMessage : readMessages) {
|
||||
SyncMessage.Read.Builder readBuilder = SyncMessage.Read.newBuilder().setTimestamp(readMessage.getTimestamp());
|
||||
|
||||
readBuilder.setSenderUuid(readMessage.getSender().getAci().toString());
|
||||
readBuilder.setSenderUuid(readMessage.getSender().getServiceId().toString());
|
||||
|
||||
if (readMessage.getSender().getNumber().isPresent()) {
|
||||
readBuilder.setSenderE164(readMessage.getSender().getNumber().get());
|
||||
|
@ -1131,7 +1131,7 @@ public class SignalServiceMessageSender {
|
|||
for (ViewedMessage readMessage : readMessages) {
|
||||
SyncMessage.Viewed.Builder viewedBuilder = SyncMessage.Viewed.newBuilder().setTimestamp(readMessage.getTimestamp());
|
||||
|
||||
viewedBuilder.setSenderUuid(readMessage.getSender().getAci().toString());
|
||||
viewedBuilder.setSenderUuid(readMessage.getSender().getServiceId().toString());
|
||||
|
||||
if (readMessage.getSender().getNumber().isPresent()) {
|
||||
viewedBuilder.setSenderE164(readMessage.getSender().getNumber().get());
|
||||
|
@ -1148,7 +1148,7 @@ public class SignalServiceMessageSender {
|
|||
SyncMessage.Builder builder = createSyncMessageBuilder();
|
||||
SyncMessage.ViewOnceOpen.Builder viewOnceBuilder = SyncMessage.ViewOnceOpen.newBuilder().setTimestamp(readMessage.getTimestamp());
|
||||
|
||||
viewOnceBuilder.setSenderUuid(readMessage.getSender().getAci().toString());
|
||||
viewOnceBuilder.setSenderUuid(readMessage.getSender().getServiceId().toString());
|
||||
|
||||
if (readMessage.getSender().getNumber().isPresent()) {
|
||||
viewOnceBuilder.setSenderE164(readMessage.getSender().getNumber().get());
|
||||
|
@ -1165,7 +1165,7 @@ public class SignalServiceMessageSender {
|
|||
SyncMessage.Blocked.Builder blockedMessage = SyncMessage.Blocked.newBuilder();
|
||||
|
||||
for (SignalServiceAddress address : blocked.getAddresses()) {
|
||||
blockedMessage.addUuids(address.getAci().toString());
|
||||
blockedMessage.addUuids(address.getServiceId().toString());
|
||||
if (address.getNumber().isPresent()) {
|
||||
blockedMessage.addNumbers(address.getNumber().get());
|
||||
}
|
||||
|
@ -1268,7 +1268,7 @@ public class SignalServiceMessageSender {
|
|||
if (message.getPerson().get().getNumber().isPresent()) {
|
||||
responseMessage.setThreadE164(message.getPerson().get().getNumber().get());
|
||||
}
|
||||
responseMessage.setThreadUuid(message.getPerson().get().getAci().toString());
|
||||
responseMessage.setThreadUuid(message.getPerson().get().getServiceId().toString());
|
||||
}
|
||||
|
||||
switch (message.getType()) {
|
||||
|
@ -1301,7 +1301,7 @@ public class SignalServiceMessageSender {
|
|||
SyncMessage.OutgoingPayment.Builder paymentMessage = SyncMessage.OutgoingPayment.newBuilder();
|
||||
|
||||
if (message.getRecipient().isPresent()) {
|
||||
paymentMessage.setRecipientUuid(message.getRecipient().get().getAci().toString());
|
||||
paymentMessage.setRecipientUuid(message.getRecipient().get().getServiceId().toString());
|
||||
}
|
||||
|
||||
if (message.getNote().isPresent()) {
|
||||
|
@ -1353,7 +1353,7 @@ public class SignalServiceMessageSender {
|
|||
|
||||
verifiedMessageBuilder.setNullMessage(ByteString.copyFrom(nullMessage));
|
||||
verifiedMessageBuilder.setIdentityKey(ByteString.copyFrom(verifiedMessage.getIdentityKey().serialize()));
|
||||
verifiedMessageBuilder.setDestinationUuid(verifiedMessage.getDestination().getAci().toString());
|
||||
verifiedMessageBuilder.setDestinationUuid(verifiedMessage.getDestination().getServiceId().toString());
|
||||
|
||||
if (verifiedMessage.getDestination().getNumber().isPresent()) {
|
||||
verifiedMessageBuilder.setDestinationE164(verifiedMessage.getDestination().getNumber().get());
|
||||
|
@ -1745,12 +1745,12 @@ public class SignalServiceMessageSender {
|
|||
|
||||
Preconditions.checkArgument(recipients.size() == unidentifiedAccess.size(), "[" + timestamp + "] Unidentified access mismatch!");
|
||||
|
||||
Map<ACI, UnidentifiedAccess> accessByAci = new HashMap<>();
|
||||
Iterator<SignalServiceAddress> addressIterator = recipients.iterator();
|
||||
Iterator<UnidentifiedAccess> accessIterator = unidentifiedAccess.iterator();
|
||||
Map<ServiceId, UnidentifiedAccess> accessBySid = new HashMap<>();
|
||||
Iterator<SignalServiceAddress> addressIterator = recipients.iterator();
|
||||
Iterator<UnidentifiedAccess> accessIterator = unidentifiedAccess.iterator();
|
||||
|
||||
while (addressIterator.hasNext()) {
|
||||
accessByAci.put(addressIterator.next().getAci(), accessIterator.next());
|
||||
accessBySid.put(addressIterator.next().getServiceId(), accessIterator.next());
|
||||
}
|
||||
|
||||
for (int i = 0; i < RETRY_COUNT; i++) {
|
||||
|
@ -1758,7 +1758,7 @@ public class SignalServiceMessageSender {
|
|||
Set<SignalProtocolAddress> sharedWith = store.getSenderKeySharedWith(distributionId);
|
||||
List<SignalServiceAddress> needsSenderKey = targetInfo.destinations.stream()
|
||||
.filter(a -> !sharedWith.contains(a))
|
||||
.map(a -> ACI.parseOrThrow(a.getName()))
|
||||
.map(a -> ServiceId.parseOrThrow(a.getName()))
|
||||
.distinct()
|
||||
.map(SignalServiceAddress::new)
|
||||
.collect(Collectors.toList());
|
||||
|
@ -1767,7 +1767,7 @@ public class SignalServiceMessageSender {
|
|||
SenderKeyDistributionMessage message = getOrCreateNewGroupSession(distributionId);
|
||||
List<Optional<UnidentifiedAccessPair>> access = needsSenderKey.stream()
|
||||
.map(r -> {
|
||||
UnidentifiedAccess targetAccess = accessByAci.get(r.getAci());
|
||||
UnidentifiedAccess targetAccess = accessBySid.get(r.getServiceId());
|
||||
return Optional.of(new UnidentifiedAccessPair(targetAccess, targetAccess));
|
||||
})
|
||||
.collect(Collectors.toList());
|
||||
|
@ -1779,8 +1779,8 @@ public class SignalServiceMessageSender {
|
|||
.map(SendMessageResult::getAddress)
|
||||
.collect(Collectors.toList());
|
||||
|
||||
Set<String> successAcis = successes.stream().map(a -> a.getAci().toString()).collect(Collectors.toSet());
|
||||
Set<SignalProtocolAddress> successAddresses = targetInfo.destinations.stream().filter(a -> successAcis.contains(a.getName())).collect(Collectors.toSet());
|
||||
Set<String> successSids = successes.stream().map(a -> a.getServiceId().toString()).collect(Collectors.toSet());
|
||||
Set<SignalProtocolAddress> successAddresses = targetInfo.destinations.stream().filter(a -> successSids.contains(a.getName())).collect(Collectors.toSet());
|
||||
|
||||
store.markSenderKeySharedWith(distributionId, successAddresses);
|
||||
|
||||
|
@ -1794,12 +1794,12 @@ public class SignalServiceMessageSender {
|
|||
.filter(r -> !r.isSuccess())
|
||||
.collect(Collectors.toList());
|
||||
|
||||
Set<ACI> failedAddresses = trueFailures.stream()
|
||||
.map(result -> result.getAddress().getAci())
|
||||
.collect(Collectors.toSet());
|
||||
Set<ServiceId> failedAddresses = trueFailures.stream()
|
||||
.map(result -> result.getAddress().getServiceId())
|
||||
.collect(Collectors.toSet());
|
||||
|
||||
List<SendMessageResult> fakeNetworkFailures = recipients.stream()
|
||||
.filter(r -> !failedAddresses.contains(r.getAci()))
|
||||
.filter(r -> !failedAddresses.contains(r.getServiceId()))
|
||||
.map(SendMessageResult::networkFailure)
|
||||
.collect(Collectors.toList());
|
||||
|
||||
|
@ -1914,7 +1914,7 @@ public class SignalServiceMessageSender {
|
|||
|
||||
List<SendMessageResult> success = recipients.keySet()
|
||||
.stream()
|
||||
.filter(r -> !unregistered.contains(r.getAci()))
|
||||
.filter(r -> !unregistered.contains(r.getServiceId()))
|
||||
.map(a -> SendMessageResult.success(a, recipients.get(a), true, store.isMultiDevice(), -1, Optional.of(content)))
|
||||
.collect(Collectors.toList());
|
||||
|
||||
|
@ -2064,7 +2064,7 @@ public class SignalServiceMessageSender {
|
|||
List<SignalProtocolAddress> addresses = new ArrayList<>(devices.size());
|
||||
|
||||
for (int staleDeviceId : devices) {
|
||||
addresses.add(new SignalProtocolAddress(recipient.getAci().toString(), staleDeviceId));
|
||||
addresses.add(new SignalProtocolAddress(recipient.getServiceId().toString(), staleDeviceId));
|
||||
|
||||
if (recipient.getNumber().isPresent()) {
|
||||
addresses.add(new SignalProtocolAddress(recipient.getNumber().get(), staleDeviceId));
|
||||
|
|
|
@ -100,7 +100,7 @@ public class SignalServiceCipher {
|
|||
PushTransportDetails transport = new PushTransportDetails();
|
||||
SignalProtocolAddress localProtocolAddress = new SignalProtocolAddress(localAddress.getIdentifier(), localDeviceId);
|
||||
SignalGroupCipher groupCipher = new SignalGroupCipher(sessionLock, new GroupCipher(signalProtocolStore, localProtocolAddress));
|
||||
SignalSealedSessionCipher sessionCipher = new SignalSealedSessionCipher(sessionLock, new SealedSessionCipher(signalProtocolStore, localAddress.getAci().uuid(), localAddress.getNumber().orNull(), localDeviceId));
|
||||
SignalSealedSessionCipher sessionCipher = new SignalSealedSessionCipher(sessionLock, new SealedSessionCipher(signalProtocolStore, localAddress.getServiceId().uuid(), localAddress.getNumber().orNull(), localDeviceId));
|
||||
CiphertextMessage message = groupCipher.encrypt(distributionId.asUuid(), transport.getPaddedMessageBody(unpaddedMessage));
|
||||
UnidentifiedSenderMessageContent messageContent = new UnidentifiedSenderMessageContent(message,
|
||||
senderCertificate,
|
||||
|
@ -117,7 +117,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.getAci().uuid(), localAddress.getNumber().orNull(), localDeviceId));
|
||||
SignalSealedSessionCipher sealedSessionCipher = new SignalSealedSessionCipher(sessionLock, new SealedSessionCipher(signalProtocolStore, localAddress.getServiceId().uuid(), localAddress.getNumber().orNull(), localDeviceId));
|
||||
|
||||
return content.processSealedSender(sessionCipher, sealedSessionCipher, destination, unidentifiedAccess.get().getUnidentifiedCertificate());
|
||||
} else {
|
||||
|
@ -208,7 +208,7 @@ public class SignalServiceCipher {
|
|||
paddedMessage = new PlaintextContent(ciphertext).getBody();
|
||||
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.getAci().uuid(), localAddress.getNumber().orNull(), localDeviceId));
|
||||
SignalSealedSessionCipher sealedSessionCipher = new SignalSealedSessionCipher(sessionLock, new SealedSessionCipher(signalProtocolStore, localAddress.getServiceId().uuid(), localAddress.getNumber().orNull(), localDeviceId));
|
||||
DecryptionResult result = sealedSessionCipher.decrypt(certificateValidator, ciphertext, envelope.getServerReceivedTimestamp());
|
||||
SignalServiceAddress resultAddress = new SignalServiceAddress(ACI.parseOrThrow(result.getSenderUuid()), result.getSenderE164());
|
||||
Optional<byte[]> groupId = result.getGroupId();
|
||||
|
|
|
@ -11,6 +11,7 @@ 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.ServiceId;
|
||||
import org.whispersystems.signalservice.api.push.SignalServiceAddress;
|
||||
import org.whispersystems.signalservice.api.util.OptionalUtil;
|
||||
|
||||
|
@ -610,17 +611,17 @@ public class SignalServiceDataMessage {
|
|||
}
|
||||
|
||||
public static class Mention {
|
||||
private final ACI aci;
|
||||
private final int start;
|
||||
private final int length;
|
||||
private final ServiceId aci;
|
||||
private final int start;
|
||||
private final int length;
|
||||
|
||||
public Mention(ACI aci, int start, int length) {
|
||||
public Mention(ServiceId aci, int start, int length) {
|
||||
this.aci = aci;
|
||||
this.start = start;
|
||||
this.length = length;
|
||||
}
|
||||
|
||||
public ACI getAci() {
|
||||
public ServiceId getAci() {
|
||||
return aci;
|
||||
}
|
||||
|
||||
|
|
|
@ -12,7 +12,6 @@ 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;
|
||||
import org.whispersystems.signalservice.internal.serialize.protos.SignalServiceEnvelopeProto;
|
||||
import org.whispersystems.util.Base64;
|
||||
|
@ -71,7 +70,7 @@ public class SignalServiceEnvelope {
|
|||
.setServerTimestamp(serverReceivedTimestamp);
|
||||
|
||||
if (sender.isPresent()) {
|
||||
builder.setSourceUuid(sender.get().getAci().toString());
|
||||
builder.setSourceUuid(sender.get().getServiceId().toString());
|
||||
|
||||
if (sender.get().getNumber().isPresent()) {
|
||||
builder.setSourceE164(sender.get().getNumber().get());
|
||||
|
|
|
@ -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().getAci().toString());
|
||||
contactDetails.setUuid(contact.getAddress().getServiceId().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().getAci().toString())
|
||||
.setDestinationUuid(contact.getVerified().get().getDestination().getServiceId().toString())
|
||||
.setState(state);
|
||||
|
||||
if (contact.getVerified().get().getDestination().getNumber().isPresent()) {
|
||||
|
|
|
@ -8,7 +8,7 @@ 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.ServiceId;
|
||||
import org.whispersystems.signalservice.api.push.SignalServiceAddress;
|
||||
|
||||
import java.util.HashMap;
|
||||
|
@ -21,26 +21,29 @@ public class SentTranscriptMessage {
|
|||
private final long timestamp;
|
||||
private final long expirationStartTimestamp;
|
||||
private final SignalServiceDataMessage message;
|
||||
private final Map<String, Boolean> unidentifiedStatusByAci;
|
||||
private final Map<String, Boolean> unidentifiedStatusBySid;
|
||||
private final Map<String, Boolean> unidentifiedStatusByE164;
|
||||
private final Set<SignalServiceAddress> recipients;
|
||||
private final boolean isRecipientUpdate;
|
||||
|
||||
public SentTranscriptMessage(Optional<SignalServiceAddress> destination, long timestamp, SignalServiceDataMessage message,
|
||||
long expirationStartTimestamp, Map<SignalServiceAddress, Boolean> unidentifiedStatus,
|
||||
public SentTranscriptMessage(Optional<SignalServiceAddress> destination,
|
||||
long timestamp,
|
||||
SignalServiceDataMessage message,
|
||||
long expirationStartTimestamp,
|
||||
Map<SignalServiceAddress, Boolean> unidentifiedStatus,
|
||||
boolean isRecipientUpdate)
|
||||
{
|
||||
this.destination = destination;
|
||||
this.timestamp = timestamp;
|
||||
this.message = message;
|
||||
this.expirationStartTimestamp = expirationStartTimestamp;
|
||||
this.unidentifiedStatusByAci = new HashMap<>();
|
||||
this.unidentifiedStatusBySid = new HashMap<>();
|
||||
this.unidentifiedStatusByE164 = new HashMap<>();
|
||||
this.recipients = unidentifiedStatus.keySet();
|
||||
this.isRecipientUpdate = isRecipientUpdate;
|
||||
|
||||
for (Map.Entry<SignalServiceAddress, Boolean> entry : unidentifiedStatus.entrySet()) {
|
||||
unidentifiedStatusByAci.put(entry.getKey().getAci().toString(), entry.getValue());
|
||||
unidentifiedStatusBySid.put(entry.getKey().getServiceId().toString(), entry.getValue());
|
||||
|
||||
if (entry.getKey().getNumber().isPresent()) {
|
||||
unidentifiedStatusByE164.put(entry.getKey().getNumber().get(), entry.getValue());
|
||||
|
@ -64,13 +67,13 @@ public class SentTranscriptMessage {
|
|||
return message;
|
||||
}
|
||||
|
||||
public boolean isUnidentified(ACI aci) {
|
||||
return isUnidentified(aci.toString());
|
||||
public boolean isUnidentified(ServiceId serviceId) {
|
||||
return isUnidentified(serviceId.toString());
|
||||
}
|
||||
|
||||
public boolean isUnidentified(String destination) {
|
||||
if (unidentifiedStatusByAci.containsKey(destination)) {
|
||||
return unidentifiedStatusByAci.get(destination);
|
||||
if (unidentifiedStatusBySid.containsKey(destination)) {
|
||||
return unidentifiedStatusBySid.get(destination);
|
||||
} else if (unidentifiedStatusByE164.containsKey(destination)) {
|
||||
return unidentifiedStatusByE164.get(destination);
|
||||
} else {
|
||||
|
|
|
@ -2,19 +2,15 @@ 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;
|
||||
|
||||
/**
|
||||
* 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 extends AccountIdentifier {
|
||||
public final class ACI extends ServiceId {
|
||||
|
||||
public static final ACI UNKNOWN = ACI.from(UuidUtil.UNKNOWN_UUID);
|
||||
|
||||
|
@ -22,51 +18,15 @@ public final class ACI extends AccountIdentifier {
|
|||
return new ACI(uuid);
|
||||
}
|
||||
|
||||
public static Optional<ACI> 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<ACI> filterKnown(Collection<ACI> acis) {
|
||||
return acis.stream().filter(aci -> !aci.equals(UNKNOWN)).collect(Collectors.toList());
|
||||
}
|
||||
|
||||
private ACI(UUID uuid) {
|
||||
super(uuid);
|
||||
}
|
||||
|
@ -79,13 +39,13 @@ public final class ACI extends AccountIdentifier {
|
|||
return UuidUtil.toByteArray(uuid);
|
||||
}
|
||||
|
||||
public boolean isUnknown() {
|
||||
return this.equals(UNKNOWN);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isAci() {
|
||||
return true;
|
||||
public boolean equals(Object other) {
|
||||
if (other instanceof ServiceId) {
|
||||
return uuid.equals(((ServiceId) other).uuid);
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -93,15 +53,6 @@ public final class ACI extends AccountIdentifier {
|
|||
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();
|
||||
|
|
|
@ -1,30 +0,0 @@
|
|||
package org.whispersystems.signalservice.api.push;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
/**
|
||||
* A wrapper around a UUID that represents an identifier for an account. Today, that is either an {@link ACI} or a {@link PNI}.
|
||||
*/
|
||||
public abstract class AccountIdentifier {
|
||||
|
||||
protected final UUID uuid;
|
||||
|
||||
protected AccountIdentifier(UUID uuid) {
|
||||
this.uuid = uuid;
|
||||
}
|
||||
|
||||
public UUID uuid() {
|
||||
return uuid;
|
||||
}
|
||||
|
||||
public abstract boolean isAci();
|
||||
|
||||
public final boolean isPni() {
|
||||
return !isAci();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return uuid.toString();
|
||||
}
|
||||
}
|
|
@ -8,7 +8,7 @@ import java.util.UUID;
|
|||
* A PNI is a "Phone Number 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 PNI extends AccountIdentifier {
|
||||
public final class PNI extends ServiceId {
|
||||
|
||||
public static PNI from(UUID uuid) {
|
||||
return new PNI(uuid);
|
||||
|
@ -27,11 +27,6 @@ public final class PNI extends AccountIdentifier {
|
|||
super(uuid);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isAci() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return uuid.hashCode();
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Reference in a new issue