Improve and centralize e164 utils.

This commit is contained in:
Greyson Parrelli
2025-03-03 10:42:21 -05:00
parent 0fdcc1c027
commit 9c473fb570
99 changed files with 748 additions and 1826 deletions

View File

@@ -9,7 +9,6 @@ import io.reactivex.rxjava3.disposables.CompositeDisposable
import io.reactivex.rxjava3.disposables.Disposable
import io.reactivex.rxjava3.kotlin.plusAssign
import io.reactivex.rxjava3.schedulers.Schedulers
import org.thoughtcrime.securesms.dependencies.AppDependencies
import org.thoughtcrime.securesms.recipients.Recipient
import org.thoughtcrime.securesms.recipients.RecipientId
import org.thoughtcrime.securesms.util.rx.RxStore
@@ -74,7 +73,7 @@ class ContactChipViewModel : ViewModel() {
private fun getOrCreateRecipientId(selectedContact: SelectedContact): Single<RecipientId> {
return Single.fromCallable {
selectedContact.getOrCreateRecipientId(AppDependencies.application)
selectedContact.getOrCreateRecipientId()
}
}
}

View File

@@ -12,7 +12,7 @@ import org.signal.libsignal.protocol.util.Pair;
import org.thoughtcrime.securesms.contacts.paged.ContactSearchSortOrder;
import org.thoughtcrime.securesms.database.RecipientTable;
import org.thoughtcrime.securesms.database.SignalDatabase;
import org.thoughtcrime.securesms.phonenumbers.PhoneNumberFormatter;
import org.thoughtcrime.securesms.util.SignalE164Util;
import org.thoughtcrime.securesms.util.Util;
import java.util.ArrayList;
@@ -59,7 +59,7 @@ public class ContactRepository {
String email = CursorUtil.requireString(cursor, RecipientTable.EMAIL);
if (phone != null) {
phone = PhoneNumberFormatter.prettyPrint(phone);
phone = SignalE164Util.prettyPrint(phone);
}
return Util.getFirstNonEmpty(phone, email);

View File

@@ -16,9 +16,9 @@ import org.thoughtcrime.securesms.database.SignalDatabase;
import org.thoughtcrime.securesms.dependencies.AppDependencies;
import org.thoughtcrime.securesms.jobs.DirectoryRefreshJob;
import org.thoughtcrime.securesms.keyvalue.SignalStore;
import org.thoughtcrime.securesms.phonenumbers.PhoneNumberFormatter;
import org.thoughtcrime.securesms.recipients.Recipient;
import org.signal.core.util.SetUtil;
import org.thoughtcrime.securesms.util.SignalE164Util;
import java.io.IOException;
import java.util.List;
@@ -56,7 +56,8 @@ public class ContactsSyncAdapter extends AbstractThreadedSyncAdapter {
Set<String> allSystemE164s = SystemContactsRepository.getAllDisplayNumbers(context)
.stream()
.map(number -> PhoneNumberFormatter.get(context).format(number))
.map(number -> SignalE164Util.formatAsE164(number))
.filter(it -> it != null)
.collect(Collectors.toSet());
Set<String> knownSystemE164s = SignalDatabase.recipients().getAllE164s();
Set<String> unknownSystemE164s = SetUtil.difference(allSystemE164s, knownSystemE164s);
@@ -71,7 +72,8 @@ public class ContactsSyncAdapter extends AbstractThreadedSyncAdapter {
} else if (unknownSystemE164s.size() > 0) {
List<Recipient> recipients = Stream.of(unknownSystemE164s)
.filter(s -> s.startsWith("+"))
.map(s -> Recipient.external(getContext(), s))
.map(s -> Recipient.external(s))
.filter(it -> it != null)
.toList();
Log.i(TAG, "There are " + unknownSystemE164s.size() + " unknown E164s, which are now " + recipients.size() + " recipients. Only syncing these specific contacts.");

View File

@@ -1,7 +1,5 @@
package org.thoughtcrime.securesms.contacts;
import android.content.Context;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
@@ -45,11 +43,16 @@ public final class SelectedContact {
this.chatType = chatType;
}
public @NonNull RecipientId getOrCreateRecipientId(@NonNull Context context) {
public @NonNull RecipientId getOrCreateRecipientId() {
if (recipientId != null) {
return recipientId;
} else if (number != null) {
return Recipient.external(context, number).getId();
Recipient recipient = Recipient.external(number);
if (recipient != null) {
return recipient.getId();
} else {
throw new AssertionError("Invalid phone number provided!");
}
} else {
throw new AssertionError();
}

View File

@@ -7,6 +7,7 @@ import androidx.annotation.WorkerThread
import org.signal.contacts.SystemContactsRepository
import org.signal.contacts.SystemContactsRepository.ContactIterator
import org.signal.contacts.SystemContactsRepository.ContactPhoneDetails
import org.signal.core.util.E164Util
import org.signal.core.util.Stopwatch
import org.signal.core.util.StringUtil
import org.signal.core.util.logging.Log
@@ -19,7 +20,6 @@ import org.thoughtcrime.securesms.mms.IncomingMessage
import org.thoughtcrime.securesms.notifications.NotificationChannels
import org.thoughtcrime.securesms.notifications.v2.ConversationId
import org.thoughtcrime.securesms.permissions.Permissions
import org.thoughtcrime.securesms.phonenumbers.PhoneNumberFormatter
import org.thoughtcrime.securesms.profiles.ProfileName
import org.thoughtcrime.securesms.recipients.Recipient
import org.thoughtcrime.securesms.recipients.RecipientId
@@ -141,8 +141,9 @@ object ContactDiscovery {
)
}
private fun phoneNumberFormatter(context: Context): (String) -> String {
return { PhoneNumberFormatter.get(context).format(it) }
private fun phoneNumberFormatter(): (String) -> String? {
val formatter = E164Util.createFormatterForE164(SignalStore.account.e164!!)
return { formatter.formatAsE164(it) }
}
private fun refreshRecipients(
@@ -171,13 +172,13 @@ object ContactDiscovery {
contactsProvider = {
if (useFullSync) {
Log.d(TAG, "Doing a full system contact sync. There are ${result.registeredIds.size} contacts to get info for.")
SystemContactsRepository.getAllSystemContacts(context, phoneNumberFormatter(context))
SystemContactsRepository.getAllSystemContacts(context, phoneNumberFormatter())
} else {
Log.d(TAG, "Doing a partial system contact sync. There are ${result.registeredIds.size} contacts to get info for.")
SystemContactsRepository.getContactDetailsByQueries(
context = context,
queries = Recipient.resolvedList(result.registeredIds).mapNotNull { it.e164.orElse(null) },
e164Formatter = phoneNumberFormatter(context)
e164Formatter = phoneNumberFormatter()
)
}
},
@@ -235,7 +236,7 @@ object ContactDiscovery {
private fun syncRecipientsWithSystemContacts(
context: Context,
rewrites: Map<String, String>,
contactsProvider: () -> ContactIterator = { SystemContactsRepository.getAllSystemContacts(context, phoneNumberFormatter(context)) },
contactsProvider: () -> ContactIterator = { SystemContactsRepository.getAllSystemContacts(context, phoneNumberFormatter()) },
clearInfoForMissingContacts: Boolean
) {
val localNumber: String = SignalStore.account.e164 ?: ""
@@ -259,8 +260,10 @@ object ContactDiscovery {
ProfileName.EMPTY
}
val recipient: Recipient = Recipient.externalContact(realNumber) ?: continue
handle.setSystemContactInfo(
Recipient.externalContact(realNumber).id,
recipient.id,
profileName,
phoneDetails.displayName,
phoneDetails.photoUri,

View File

@@ -11,10 +11,10 @@ import org.thoughtcrime.securesms.database.RecipientTable.CdsV2Result
import org.thoughtcrime.securesms.database.SignalDatabase
import org.thoughtcrime.securesms.dependencies.AppDependencies
import org.thoughtcrime.securesms.keyvalue.SignalStore
import org.thoughtcrime.securesms.phonenumbers.PhoneNumberFormatter
import org.thoughtcrime.securesms.recipients.Recipient
import org.thoughtcrime.securesms.recipients.RecipientId
import org.thoughtcrime.securesms.util.RemoteConfig
import org.thoughtcrime.securesms.util.SignalE164Util
import org.whispersystems.signalservice.api.push.exceptions.CdsiInvalidTokenException
import org.whispersystems.signalservice.api.push.exceptions.CdsiResourceExhaustedException
import org.whispersystems.signalservice.api.services.CdsiV2Service
@@ -45,7 +45,7 @@ object ContactDiscoveryRefreshV2 {
@JvmStatic
fun refreshAll(context: Context, timeoutMs: Long? = null): ContactDiscovery.RefreshResult {
val recipientE164s: Set<String> = SignalDatabase.recipients.getAllE164s().sanitize()
val systemE164s: Set<String> = SystemContactsRepository.getAllDisplayNumbers(context).toE164s(context).sanitize()
val systemE164s: Set<String> = SystemContactsRepository.getAllDisplayNumbers(context).toE164s().sanitize()
return refreshInternal(
recipientE164s = recipientE164s,
@@ -246,8 +246,8 @@ object ContactDiscoveryRefreshV2 {
.toSet()
}
private fun Set<String>.toE164s(context: Context): Set<String> {
return this.map { PhoneNumberFormatter.get(context).format(it) }.toSet()
private fun Set<String>.toE164s(): Set<String> {
return this.mapNotNull { SignalE164Util.formatAsE164(it) }.toSet()
}
private fun Set<String>.sanitize(): Set<String> {