mirror of
https://github.com/signalapp/Signal-Android.git
synced 2026-04-22 01:40:07 +01:00
Improve and centralize e164 utils.
This commit is contained in:
@@ -40,9 +40,9 @@ import org.thoughtcrime.securesms.groups.GroupId
|
||||
import org.thoughtcrime.securesms.keyvalue.SignalStore
|
||||
import org.thoughtcrime.securesms.notifications.NotificationChannels
|
||||
import org.thoughtcrime.securesms.phonenumbers.NumberUtil
|
||||
import org.thoughtcrime.securesms.phonenumbers.PhoneNumberFormatter
|
||||
import org.thoughtcrime.securesms.profiles.ProfileName
|
||||
import org.thoughtcrime.securesms.service.webrtc.links.CallLinkRoomId
|
||||
import org.thoughtcrime.securesms.util.SignalE164Util
|
||||
import org.thoughtcrime.securesms.util.UsernameUtil.isValidUsernameForSearch
|
||||
import org.thoughtcrime.securesms.util.Util
|
||||
import org.thoughtcrime.securesms.wallpaper.ChatWallpaper
|
||||
@@ -556,7 +556,7 @@ class Recipient(
|
||||
}
|
||||
|
||||
if (name.isBlank() && e164Value.isNotNullOrBlank()) {
|
||||
name = PhoneNumberFormatter.prettyPrint(e164Value)
|
||||
name = SignalE164Util.prettyPrint(e164Value)
|
||||
}
|
||||
|
||||
if (name.isBlank() && emailValue != null) {
|
||||
@@ -587,7 +587,7 @@ class Recipient(
|
||||
}
|
||||
|
||||
if (name.isBlank() && e164Value.isNotNullOrBlank()) {
|
||||
name = PhoneNumberFormatter.prettyPrint(e164Value)
|
||||
name = SignalE164Util.prettyPrint(e164Value)
|
||||
}
|
||||
|
||||
if (name.isBlank()) {
|
||||
@@ -901,6 +901,37 @@ class Recipient(
|
||||
return externalPush(serviceId, null)
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a fully-populated [Recipient] based off of a ServiceId and phone number, creating one
|
||||
* in the database if necessary. We want both piece of information so we're able to associate them
|
||||
* both together, depending on which are available.
|
||||
*
|
||||
* In particular, while we may eventually get the ACI of a user created via a phone number
|
||||
* (through a directory sync), the only way we can store the phone number is by retrieving it from
|
||||
* sent messages and whatnot. So we should store it when available.
|
||||
*/
|
||||
@JvmStatic
|
||||
@WorkerThread
|
||||
private fun externalPush(serviceId: ServiceId, e164: String?): Recipient {
|
||||
if (ACI.UNKNOWN == serviceId || PNI.UNKNOWN == serviceId) {
|
||||
throw AssertionError()
|
||||
}
|
||||
|
||||
val recipientId = RecipientId.from(SignalServiceAddress(serviceId, e164))
|
||||
val resolved = resolved(recipientId)
|
||||
|
||||
if (resolved.id != recipientId) {
|
||||
Log.w(TAG, "Resolved $recipientId, but got back a recipient with ${resolved.id}")
|
||||
}
|
||||
|
||||
if (!resolved.isRegistered) {
|
||||
Log.w(TAG, "External push was locally marked unregistered. Marking as registered.")
|
||||
SignalDatabase.recipients.markRegistered(recipientId, serviceId)
|
||||
}
|
||||
|
||||
return resolved
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a recipient with a full (ACI, PNI, E164) tuple. It is assumed that the association between the PNI and serviceId is trusted.
|
||||
* That means it must be from either storage service (with the verified field set) or a PNI verification message.
|
||||
@@ -927,39 +958,6 @@ class Recipient(
|
||||
return resolved
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a fully-populated [Recipient] based off of a ServiceId and phone number, creating one
|
||||
* in the database if necessary. We want both piece of information so we're able to associate them
|
||||
* both together, depending on which are available.
|
||||
*
|
||||
* In particular, while we may eventually get the ACI of a user created via a phone number
|
||||
* (through a directory sync), the only way we can store the phone number is by retrieving it from
|
||||
* sent messages and whatnot. So we should store it when available.
|
||||
*/
|
||||
@JvmStatic
|
||||
@WorkerThread
|
||||
fun externalPush(serviceId: ServiceId?, e164: String?): Recipient {
|
||||
if (ACI.UNKNOWN == serviceId || PNI.UNKNOWN == serviceId) {
|
||||
throw AssertionError()
|
||||
}
|
||||
|
||||
val recipientId = RecipientId.from(SignalServiceAddress(serviceId, e164))
|
||||
val resolved = resolved(recipientId)
|
||||
|
||||
if (resolved.id != recipientId) {
|
||||
Log.w(TAG, "Resolved $recipientId, but got back a recipient with ${resolved.id}")
|
||||
}
|
||||
|
||||
if (!resolved.isRegistered && serviceId != null) {
|
||||
Log.w(TAG, "External push was locally marked unregistered. Marking as registered.")
|
||||
SignalDatabase.recipients.markRegistered(recipientId, serviceId)
|
||||
} else if (!resolved.isRegistered) {
|
||||
Log.w(TAG, "External push was locally marked unregistered, but we don't have an ACI, so we can't do anything.", Throwable())
|
||||
}
|
||||
|
||||
return resolved
|
||||
}
|
||||
|
||||
/**
|
||||
* A safety wrapper around [.external] for when you know you're using an
|
||||
* identifier for a system contact, and therefore always want to prevent interpreting it as a
|
||||
@@ -969,13 +967,14 @@ class Recipient(
|
||||
*/
|
||||
@JvmStatic
|
||||
@WorkerThread
|
||||
fun externalContact(identifier: String): Recipient {
|
||||
fun externalContact(identifier: String): Recipient? {
|
||||
val id: RecipientId = if (UuidUtil.isUuid(identifier)) {
|
||||
throw AssertionError("UUIDs are not valid system contact identifiers!")
|
||||
} else if (NumberUtil.isValidEmail(identifier)) {
|
||||
SignalDatabase.recipients.getOrInsertFromEmail(identifier)
|
||||
} else {
|
||||
SignalDatabase.recipients.getOrInsertFromE164(identifier)
|
||||
val e164 = SignalE164Util.formatAsE164(identifier) ?: return null
|
||||
SignalDatabase.recipients.getOrInsertFromE164(e164)
|
||||
}
|
||||
|
||||
return resolved(id)
|
||||
@@ -1027,10 +1026,13 @@ class Recipient(
|
||||
* If the identifier is a UUID of a Signal user, prefer using
|
||||
* [.externalPush] or its overload, as this will let us associate
|
||||
* the phone number with the recipient.
|
||||
*
|
||||
* Important: If the identifier cannot be considered a valid UUID, groupId, email, or phone number,
|
||||
* this will return null.
|
||||
*/
|
||||
@JvmStatic
|
||||
@WorkerThread
|
||||
fun external(context: Context, identifier: String): Recipient {
|
||||
fun external(identifier: String): Recipient? {
|
||||
val serviceId = ServiceId.parseOrNull(identifier, logFailures = false)
|
||||
|
||||
val id: RecipientId = if (serviceId != null) {
|
||||
@@ -1042,7 +1044,7 @@ class Recipient(
|
||||
} else if (isValidUsernameForSearch(identifier)) {
|
||||
throw IllegalArgumentException("Creating a recipient based on username alone is not supported!")
|
||||
} else {
|
||||
val e164 = PhoneNumberFormatter.get(context).format(identifier)
|
||||
val e164: String = SignalE164Util.formatAsE164(identifier) ?: return null
|
||||
SignalDatabase.recipients.getOrInsertFromE164(e164)
|
||||
}
|
||||
|
||||
|
||||
@@ -5,13 +5,12 @@
|
||||
|
||||
package org.thoughtcrime.securesms.recipients
|
||||
|
||||
import android.content.Context
|
||||
import androidx.annotation.WorkerThread
|
||||
import org.signal.core.util.logging.Log
|
||||
import org.thoughtcrime.securesms.contacts.sync.ContactDiscovery
|
||||
import org.thoughtcrime.securesms.database.SignalDatabase
|
||||
import org.thoughtcrime.securesms.phonenumbers.NumberUtil
|
||||
import org.thoughtcrime.securesms.phonenumbers.PhoneNumberFormatter
|
||||
import org.thoughtcrime.securesms.util.SignalE164Util
|
||||
import java.io.IOException
|
||||
|
||||
/**
|
||||
@@ -29,10 +28,10 @@ object RecipientRepository {
|
||||
*/
|
||||
@WorkerThread
|
||||
@JvmStatic
|
||||
fun lookupNewE164(context: Context, inputE164: String): LookupResult {
|
||||
val e164 = PhoneNumberFormatter.get(context).format(inputE164)
|
||||
fun lookupNewE164(inputE164: String): LookupResult {
|
||||
val e164 = SignalE164Util.formatAsE164(inputE164)
|
||||
|
||||
if (!NumberUtil.isVisuallyValidNumber(e164)) {
|
||||
if (e164 == null || !NumberUtil.isVisuallyValidNumber(e164)) {
|
||||
return LookupResult.InvalidEntry
|
||||
}
|
||||
|
||||
|
||||
@@ -51,10 +51,10 @@ import org.thoughtcrime.securesms.components.emoji.EmojiTextView
|
||||
import org.thoughtcrime.securesms.compose.ComposeBottomSheetDialogFragment
|
||||
import org.thoughtcrime.securesms.conversation.v2.UnverifiedProfileNameBottomSheet
|
||||
import org.thoughtcrime.securesms.nicknames.ViewNoteSheet
|
||||
import org.thoughtcrime.securesms.phonenumbers.PhoneNumberFormatter
|
||||
import org.thoughtcrime.securesms.recipients.Recipient
|
||||
import org.thoughtcrime.securesms.recipients.RecipientId
|
||||
import org.thoughtcrime.securesms.stories.settings.my.SignalConnectionsBottomSheetDialogFragment
|
||||
import org.thoughtcrime.securesms.util.SignalE164Util
|
||||
import org.thoughtcrime.securesms.util.viewModel
|
||||
|
||||
/**
|
||||
@@ -103,7 +103,7 @@ class AboutSheet : ComposeBottomSheetDialogFragment() {
|
||||
hasAvatar = recipient.get().profileAvatarFileDetails.hasFile(),
|
||||
recipientForAvatar = recipient.get(),
|
||||
formattedE164 = if (recipient.get().hasE164 && recipient.get().shouldShowE164) {
|
||||
PhoneNumberFormatter.get(requireContext()).prettyPrintFormat(recipient.get().requireE164())
|
||||
SignalE164Util.prettyPrint(recipient.get().requireE164())
|
||||
} else {
|
||||
null
|
||||
},
|
||||
|
||||
@@ -68,6 +68,7 @@ import org.signal.core.ui.Previews
|
||||
import org.signal.core.ui.Scaffolds
|
||||
import org.signal.core.ui.TextFields
|
||||
import org.signal.core.ui.theme.SignalTheme
|
||||
import org.signal.core.util.E164Util
|
||||
import org.signal.core.util.getParcelableExtraCompat
|
||||
import org.thoughtcrime.securesms.PassphraseRequiredActivity
|
||||
import org.thoughtcrime.securesms.R
|
||||
@@ -80,7 +81,6 @@ import org.thoughtcrime.securesms.registration.ui.countrycode.CountryCodeSelectS
|
||||
import org.thoughtcrime.securesms.registration.ui.countrycode.CountryCodeState
|
||||
import org.thoughtcrime.securesms.util.DynamicNoActionBarTheme
|
||||
import org.thoughtcrime.securesms.util.viewModel
|
||||
import org.whispersystems.signalservice.api.util.PhoneNumberFormatter
|
||||
import org.signal.core.ui.R as CoreUiR
|
||||
|
||||
/**
|
||||
@@ -193,9 +193,9 @@ class FindByActivity : PassphraseRequiredActivity() {
|
||||
} else {
|
||||
val formattedNumber = remember(state.userEntry) {
|
||||
val cleansed = state.userEntry.removePrefix(state.selectedCountry.countryCode.toString())
|
||||
PhoneNumberFormatter.formatE164(state.selectedCountry.countryCode.toString(), cleansed)
|
||||
E164Util.formatAsE164WithCountryCodeForDisplay(state.selectedCountry.countryCode.toString(), cleansed)
|
||||
}
|
||||
stringResource(id = R.string.FindByActivity__s_is_not_a_valid_phone_number, formattedNumber)
|
||||
stringResource(id = R.string.FindByActivity__s_is_not_a_valid_phone_number, state.userEntry)
|
||||
}
|
||||
|
||||
Dialogs.SimpleAlertDialog(
|
||||
@@ -232,7 +232,7 @@ class FindByActivity : PassphraseRequiredActivity() {
|
||||
} else {
|
||||
val formattedNumber = remember(state.userEntry) {
|
||||
val cleansed = state.userEntry.removePrefix(state.selectedCountry.countryCode.toString())
|
||||
PhoneNumberFormatter.formatE164(state.selectedCountry.countryCode.toString(), cleansed)
|
||||
E164Util.formatAsE164WithCountryCodeForDisplay(state.selectedCountry.countryCode.toString(), cleansed)
|
||||
}
|
||||
stringResource(id = R.string.FindByActivity__s_is_not_a_signal_user_would, formattedNumber)
|
||||
}
|
||||
|
||||
@@ -81,7 +81,7 @@ class FindByViewModel(
|
||||
|
||||
val e164 = "+$countryCode$nationalNumber"
|
||||
|
||||
return when (val result = RecipientRepository.lookupNewE164(context, e164)) {
|
||||
return when (val result = RecipientRepository.lookupNewE164(e164)) {
|
||||
RecipientRepository.LookupResult.InvalidEntry -> FindByResult.InvalidEntry
|
||||
RecipientRepository.LookupResult.NetworkError -> FindByResult.NetworkError
|
||||
is RecipientRepository.LookupResult.NotFound -> FindByResult.NotFound(result.recipientId)
|
||||
|
||||
Reference in New Issue
Block a user