mirror of
https://github.com/signalapp/Signal-Android.git
synced 2025-12-21 19:48:29 +00:00
Inline the pnp feature flag.
This commit is contained in:
committed by
Cody Henthorne
parent
8ad77ac7aa
commit
c359ddf3c8
@@ -11,8 +11,6 @@ import org.signal.core.util.CursorUtil
|
|||||||
import org.thoughtcrime.securesms.profiles.ProfileName
|
import org.thoughtcrime.securesms.profiles.ProfileName
|
||||||
import org.thoughtcrime.securesms.recipients.RecipientId
|
import org.thoughtcrime.securesms.recipients.RecipientId
|
||||||
import org.thoughtcrime.securesms.testing.SignalActivityRule
|
import org.thoughtcrime.securesms.testing.SignalActivityRule
|
||||||
import org.thoughtcrime.securesms.util.FeatureFlags
|
|
||||||
import org.thoughtcrime.securesms.util.FeatureFlagsAccessor
|
|
||||||
import org.whispersystems.signalservice.api.push.ServiceId.ACI
|
import org.whispersystems.signalservice.api.push.ServiceId.ACI
|
||||||
import org.whispersystems.signalservice.api.push.ServiceId.PNI
|
import org.whispersystems.signalservice.api.push.ServiceId.PNI
|
||||||
import java.util.UUID
|
import java.util.UUID
|
||||||
@@ -167,8 +165,6 @@ class RecipientTableTest {
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun givenARecipientWithPniAndAci_whenIMarkItUnregistered_thenIExpectItToBeSplit() {
|
fun givenARecipientWithPniAndAci_whenIMarkItUnregistered_thenIExpectItToBeSplit() {
|
||||||
FeatureFlagsAccessor.forceValue(FeatureFlags.PHONE_NUMBER_PRIVACY, true)
|
|
||||||
|
|
||||||
val mainId = SignalDatabase.recipients.getAndPossiblyMerge(ACI_A, PNI_A, E164_A)
|
val mainId = SignalDatabase.recipients.getAndPossiblyMerge(ACI_A, PNI_A, E164_A)
|
||||||
|
|
||||||
SignalDatabase.recipients.markUnregistered(mainId)
|
SignalDatabase.recipients.markUnregistered(mainId)
|
||||||
@@ -185,8 +181,6 @@ class RecipientTableTest {
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun givenARecipientWithPniAndAci_whenISplitItForStorageSync_thenIExpectItToBeSplit() {
|
fun givenARecipientWithPniAndAci_whenISplitItForStorageSync_thenIExpectItToBeSplit() {
|
||||||
FeatureFlagsAccessor.forceValue(FeatureFlags.PHONE_NUMBER_PRIVACY, true)
|
|
||||||
|
|
||||||
val mainId = SignalDatabase.recipients.getAndPossiblyMerge(ACI_A, PNI_A, E164_A)
|
val mainId = SignalDatabase.recipients.getAndPossiblyMerge(ACI_A, PNI_A, E164_A)
|
||||||
val mainRecord = SignalDatabase.recipients.getRecord(mainId)
|
val mainRecord = SignalDatabase.recipients.getRecord(mainId)
|
||||||
|
|
||||||
|
|||||||
@@ -41,8 +41,6 @@ import org.thoughtcrime.securesms.mms.IncomingMessage
|
|||||||
import org.thoughtcrime.securesms.notifications.profiles.NotificationProfile
|
import org.thoughtcrime.securesms.notifications.profiles.NotificationProfile
|
||||||
import org.thoughtcrime.securesms.recipients.Recipient
|
import org.thoughtcrime.securesms.recipients.Recipient
|
||||||
import org.thoughtcrime.securesms.recipients.RecipientId
|
import org.thoughtcrime.securesms.recipients.RecipientId
|
||||||
import org.thoughtcrime.securesms.util.FeatureFlags
|
|
||||||
import org.thoughtcrime.securesms.util.FeatureFlagsAccessor
|
|
||||||
import org.thoughtcrime.securesms.util.Util
|
import org.thoughtcrime.securesms.util.Util
|
||||||
import org.whispersystems.signalservice.api.push.ServiceId.ACI
|
import org.whispersystems.signalservice.api.push.ServiceId.ACI
|
||||||
import org.whispersystems.signalservice.api.push.ServiceId.PNI
|
import org.whispersystems.signalservice.api.push.ServiceId.PNI
|
||||||
@@ -58,7 +56,6 @@ class RecipientTableTest_getAndPossiblyMerge {
|
|||||||
SignalStore.account().setE164(E164_SELF)
|
SignalStore.account().setE164(E164_SELF)
|
||||||
SignalStore.account().setAci(ACI_SELF)
|
SignalStore.account().setAci(ACI_SELF)
|
||||||
SignalStore.account().setPni(PNI_SELF)
|
SignalStore.account().setPni(PNI_SELF)
|
||||||
FeatureFlagsAccessor.forceValue(FeatureFlags.PHONE_NUMBER_PRIVACY, true)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
|||||||
@@ -12,8 +12,6 @@ import org.thoughtcrime.securesms.database.RecipientTable
|
|||||||
import org.thoughtcrime.securesms.database.SignalDatabase
|
import org.thoughtcrime.securesms.database.SignalDatabase
|
||||||
import org.thoughtcrime.securesms.keyvalue.SignalStore
|
import org.thoughtcrime.securesms.keyvalue.SignalStore
|
||||||
import org.thoughtcrime.securesms.recipients.RecipientId
|
import org.thoughtcrime.securesms.recipients.RecipientId
|
||||||
import org.thoughtcrime.securesms.util.FeatureFlags
|
|
||||||
import org.thoughtcrime.securesms.util.FeatureFlagsAccessor
|
|
||||||
import org.whispersystems.signalservice.api.push.ServiceId.ACI
|
import org.whispersystems.signalservice.api.push.ServiceId.ACI
|
||||||
import org.whispersystems.signalservice.api.push.ServiceId.PNI
|
import org.whispersystems.signalservice.api.push.ServiceId.PNI
|
||||||
import org.whispersystems.signalservice.api.storage.SignalContactRecord
|
import org.whispersystems.signalservice.api.storage.SignalContactRecord
|
||||||
@@ -29,7 +27,6 @@ class ContactRecordProcessorTest {
|
|||||||
SignalStore.account().setE164(E164_SELF)
|
SignalStore.account().setE164(E164_SELF)
|
||||||
SignalStore.account().setAci(ACI_SELF)
|
SignalStore.account().setAci(ACI_SELF)
|
||||||
SignalStore.account().setPni(PNI_SELF)
|
SignalStore.account().setPni(PNI_SELF)
|
||||||
FeatureFlagsAccessor.forceValue(FeatureFlags.PHONE_NUMBER_PRIVACY, true)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
|||||||
@@ -6,6 +6,6 @@ package org.thoughtcrime.securesms.util;
|
|||||||
public final class FeatureFlagsAccessor {
|
public final class FeatureFlagsAccessor {
|
||||||
|
|
||||||
public static void forceValue(String key, Object value) {
|
public static void forceValue(String key, Object value) {
|
||||||
FeatureFlags.FORCED_VALUES.put(FeatureFlags.PHONE_NUMBER_PRIVACY, true);
|
FeatureFlags.FORCED_VALUES.put(key, value);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -40,7 +40,6 @@ import org.thoughtcrime.securesms.service.KeyCachingService
|
|||||||
import org.thoughtcrime.securesms.util.CommunicationActions
|
import org.thoughtcrime.securesms.util.CommunicationActions
|
||||||
import org.thoughtcrime.securesms.util.ConversationUtil
|
import org.thoughtcrime.securesms.util.ConversationUtil
|
||||||
import org.thoughtcrime.securesms.util.ExpirationUtil
|
import org.thoughtcrime.securesms.util.ExpirationUtil
|
||||||
import org.thoughtcrime.securesms.util.FeatureFlags
|
|
||||||
import org.thoughtcrime.securesms.util.ServiceUtil
|
import org.thoughtcrime.securesms.util.ServiceUtil
|
||||||
import org.thoughtcrime.securesms.util.SpanUtil
|
import org.thoughtcrime.securesms.util.SpanUtil
|
||||||
import org.thoughtcrime.securesms.util.TextSecurePreferences
|
import org.thoughtcrime.securesms.util.TextSecurePreferences
|
||||||
@@ -119,18 +118,16 @@ class PrivacySettingsFragment : DSLSettingsFragment(R.string.preferences__privac
|
|||||||
|
|
||||||
private fun getConfiguration(state: PrivacySettingsState): DSLConfiguration {
|
private fun getConfiguration(state: PrivacySettingsState): DSLConfiguration {
|
||||||
return configure {
|
return configure {
|
||||||
if (FeatureFlags.phoneNumberPrivacy()) {
|
clickPref(
|
||||||
clickPref(
|
title = DSLSettingsText.from(R.string.preferences_app_protection__phone_number),
|
||||||
title = DSLSettingsText.from(R.string.preferences_app_protection__phone_number),
|
summary = DSLSettingsText.from(R.string.preferences_app_protection__choose_who_can_see),
|
||||||
summary = DSLSettingsText.from(R.string.preferences_app_protection__choose_who_can_see),
|
onClick = {
|
||||||
onClick = {
|
Navigation.findNavController(requireView())
|
||||||
Navigation.findNavController(requireView())
|
.safeNavigate(R.id.action_privacySettingsFragment_to_phoneNumberPrivacySettingsFragment)
|
||||||
.safeNavigate(R.id.action_privacySettingsFragment_to_phoneNumberPrivacySettingsFragment)
|
}
|
||||||
}
|
)
|
||||||
)
|
|
||||||
|
|
||||||
dividerPref()
|
dividerPref()
|
||||||
}
|
|
||||||
|
|
||||||
clickPref(
|
clickPref(
|
||||||
title = DSLSettingsText.from(R.string.PrivacySettingsFragment__blocked),
|
title = DSLSettingsText.from(R.string.PrivacySettingsFragment__blocked),
|
||||||
|
|||||||
@@ -28,7 +28,6 @@ import org.thoughtcrime.securesms.recipients.Recipient
|
|||||||
import org.thoughtcrime.securesms.recipients.RecipientForeverObserver
|
import org.thoughtcrime.securesms.recipients.RecipientForeverObserver
|
||||||
import org.thoughtcrime.securesms.recipients.RecipientId
|
import org.thoughtcrime.securesms.recipients.RecipientId
|
||||||
import org.thoughtcrime.securesms.subscription.Subscriber
|
import org.thoughtcrime.securesms.subscription.Subscriber
|
||||||
import org.thoughtcrime.securesms.util.FeatureFlags
|
|
||||||
import org.thoughtcrime.securesms.util.SpanUtil
|
import org.thoughtcrime.securesms.util.SpanUtil
|
||||||
import org.thoughtcrime.securesms.util.Util
|
import org.thoughtcrime.securesms.util.Util
|
||||||
import org.thoughtcrime.securesms.util.adapter.mapping.MappingAdapter
|
import org.thoughtcrime.securesms.util.adapter.mapping.MappingAdapter
|
||||||
@@ -260,11 +259,7 @@ class InternalConversationSettingsFragment : DSLSettingsFragment(
|
|||||||
|
|
||||||
SignalDatabase.recipients.debugClearE164AndPni(recipient.id)
|
SignalDatabase.recipients.debugClearE164AndPni(recipient.id)
|
||||||
|
|
||||||
val splitRecipientId: RecipientId = if (FeatureFlags.phoneNumberPrivacy()) {
|
val splitRecipientId: RecipientId = SignalDatabase.recipients.getAndPossiblyMergePnpVerified(null, recipient.pni.orElse(null), recipient.requireE164())
|
||||||
SignalDatabase.recipients.getAndPossiblyMergePnpVerified(null, recipient.pni.orElse(null), recipient.requireE164())
|
|
||||||
} else {
|
|
||||||
SignalDatabase.recipients.getAndPossiblyMerge(recipient.pni.orElse(null), recipient.requireE164())
|
|
||||||
}
|
|
||||||
val splitRecipient: Recipient = Recipient.resolved(splitRecipientId)
|
val splitRecipient: Recipient = Recipient.resolved(splitRecipientId)
|
||||||
val splitThreadId: Long = SignalDatabase.threads.getOrCreateThreadIdFor(splitRecipient)
|
val splitThreadId: Long = SignalDatabase.threads.getOrCreateThreadIdFor(splitRecipient)
|
||||||
|
|
||||||
@@ -287,7 +282,6 @@ class InternalConversationSettingsFragment : DSLSettingsFragment(
|
|||||||
clickPref(
|
clickPref(
|
||||||
title = DSLSettingsText.from("Split without creating threads"),
|
title = DSLSettingsText.from("Split without creating threads"),
|
||||||
summary = DSLSettingsText.from("Splits this contact into two recipients so you can test merging them together. This will become the PNI-based recipient. Another recipient will be made with this ACI and profile key. Doing a CDS refresh should allow you to see a Session Switchover Event, as long as you had a session with this PNI."),
|
summary = DSLSettingsText.from("Splits this contact into two recipients so you can test merging them together. This will become the PNI-based recipient. Another recipient will be made with this ACI and profile key. Doing a CDS refresh should allow you to see a Session Switchover Event, as long as you had a session with this PNI."),
|
||||||
isEnabled = FeatureFlags.phoneNumberPrivacy(),
|
|
||||||
onClick = {
|
onClick = {
|
||||||
MaterialAlertDialogBuilder(requireContext())
|
MaterialAlertDialogBuilder(requireContext())
|
||||||
.setTitle("Are you sure?")
|
.setTitle("Are you sure?")
|
||||||
|
|||||||
@@ -25,7 +25,6 @@ import org.thoughtcrime.securesms.recipients.Recipient
|
|||||||
import org.thoughtcrime.securesms.recipients.RecipientId
|
import org.thoughtcrime.securesms.recipients.RecipientId
|
||||||
import org.thoughtcrime.securesms.registration.RegistrationUtil
|
import org.thoughtcrime.securesms.registration.RegistrationUtil
|
||||||
import org.thoughtcrime.securesms.storage.StorageSyncHelper
|
import org.thoughtcrime.securesms.storage.StorageSyncHelper
|
||||||
import org.thoughtcrime.securesms.util.FeatureFlags
|
|
||||||
import org.thoughtcrime.securesms.util.TextSecurePreferences
|
import org.thoughtcrime.securesms.util.TextSecurePreferences
|
||||||
import org.thoughtcrime.securesms.util.Util
|
import org.thoughtcrime.securesms.util.Util
|
||||||
import org.whispersystems.signalservice.api.push.SignalServiceAddress
|
import org.whispersystems.signalservice.api.push.SignalServiceAddress
|
||||||
@@ -70,7 +69,7 @@ object ContactDiscovery {
|
|||||||
context = context,
|
context = context,
|
||||||
descriptor = "refresh-all",
|
descriptor = "refresh-all",
|
||||||
refresh = {
|
refresh = {
|
||||||
ContactDiscoveryRefreshV2.refreshAll(context, useCompat = FeatureFlags.cdsCompatMode())
|
ContactDiscoveryRefreshV2.refreshAll(context)
|
||||||
},
|
},
|
||||||
removeSystemContactLinksIfMissing = true,
|
removeSystemContactLinksIfMissing = true,
|
||||||
notifyOfNewUsers = notifyOfNewUsers,
|
notifyOfNewUsers = notifyOfNewUsers,
|
||||||
@@ -87,9 +86,7 @@ object ContactDiscovery {
|
|||||||
refreshRecipients(
|
refreshRecipients(
|
||||||
context = context,
|
context = context,
|
||||||
descriptor = "refresh-multiple",
|
descriptor = "refresh-multiple",
|
||||||
refresh = {
|
refresh = { ContactDiscoveryRefreshV2.refresh(context, recipients) },
|
||||||
ContactDiscoveryRefreshV2.refresh(context, recipients, useCompat = FeatureFlags.cdsCompatMode())
|
|
||||||
},
|
|
||||||
removeSystemContactLinksIfMissing = false,
|
removeSystemContactLinksIfMissing = false,
|
||||||
notifyOfNewUsers = notifyOfNewUsers
|
notifyOfNewUsers = notifyOfNewUsers
|
||||||
)
|
)
|
||||||
@@ -103,9 +100,7 @@ object ContactDiscovery {
|
|||||||
val result: RefreshResult = refreshRecipients(
|
val result: RefreshResult = refreshRecipients(
|
||||||
context = context,
|
context = context,
|
||||||
descriptor = "refresh-single",
|
descriptor = "refresh-single",
|
||||||
refresh = {
|
refresh = { ContactDiscoveryRefreshV2.refresh(context, listOf(recipient), timeoutMs = timeoutMs) },
|
||||||
ContactDiscoveryRefreshV2.refresh(context, listOf(recipient), useCompat = FeatureFlags.cdsCompatMode(), timeoutMs = timeoutMs)
|
|
||||||
},
|
|
||||||
removeSystemContactLinksIfMissing = false,
|
removeSystemContactLinksIfMissing = false,
|
||||||
notifyOfNewUsers = notifyOfNewUsers
|
notifyOfNewUsers = notifyOfNewUsers
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -44,7 +44,7 @@ object ContactDiscoveryRefreshV2 {
|
|||||||
@WorkerThread
|
@WorkerThread
|
||||||
@Synchronized
|
@Synchronized
|
||||||
@JvmStatic
|
@JvmStatic
|
||||||
fun refreshAll(context: Context, useCompat: Boolean, timeoutMs: Long? = null): ContactDiscovery.RefreshResult {
|
fun refreshAll(context: Context, timeoutMs: Long? = null): ContactDiscovery.RefreshResult {
|
||||||
val recipientE164s: Set<String> = SignalDatabase.recipients.getAllE164s().sanitize()
|
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(context).sanitize()
|
||||||
|
|
||||||
@@ -53,7 +53,6 @@ object ContactDiscoveryRefreshV2 {
|
|||||||
systemE164s = systemE164s,
|
systemE164s = systemE164s,
|
||||||
inputPreviousE164s = SignalDatabase.cds.getAllE164s(),
|
inputPreviousE164s = SignalDatabase.cds.getAllE164s(),
|
||||||
isPartialRefresh = false,
|
isPartialRefresh = false,
|
||||||
useCompat = useCompat,
|
|
||||||
timeoutMs = timeoutMs
|
timeoutMs = timeoutMs
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
@@ -62,14 +61,14 @@ object ContactDiscoveryRefreshV2 {
|
|||||||
@WorkerThread
|
@WorkerThread
|
||||||
@Synchronized
|
@Synchronized
|
||||||
@JvmStatic
|
@JvmStatic
|
||||||
fun refresh(context: Context, inputRecipients: List<Recipient>, useCompat: Boolean, timeoutMs: Long? = null): ContactDiscovery.RefreshResult {
|
fun refresh(context: Context, inputRecipients: List<Recipient>, timeoutMs: Long? = null): ContactDiscovery.RefreshResult {
|
||||||
val recipients: List<Recipient> = inputRecipients.map { it.resolve() }
|
val recipients: List<Recipient> = inputRecipients.map { it.resolve() }
|
||||||
val inputE164s: Set<String> = recipients.mapNotNull { it.e164.orElse(null) }.toSet().sanitize()
|
val inputE164s: Set<String> = recipients.mapNotNull { it.e164.orElse(null) }.toSet().sanitize()
|
||||||
|
|
||||||
return if (inputE164s.size > MAXIMUM_ONE_OFF_REQUEST_SIZE) {
|
return if (inputE164s.size > MAXIMUM_ONE_OFF_REQUEST_SIZE) {
|
||||||
Log.i(TAG, "List of specific recipients to refresh is too large! (Size: ${recipients.size}). Doing a full refresh instead.")
|
Log.i(TAG, "List of specific recipients to refresh is too large! (Size: ${recipients.size}). Doing a full refresh instead.")
|
||||||
|
|
||||||
val fullResult: ContactDiscovery.RefreshResult = refreshAll(context, useCompat = useCompat, timeoutMs = timeoutMs)
|
val fullResult: ContactDiscovery.RefreshResult = refreshAll(context, timeoutMs = timeoutMs)
|
||||||
val inputIds: Set<RecipientId> = recipients.map { it.id }.toSet()
|
val inputIds: Set<RecipientId> = recipients.map { it.id }.toSet()
|
||||||
|
|
||||||
ContactDiscovery.RefreshResult(
|
ContactDiscovery.RefreshResult(
|
||||||
@@ -82,7 +81,6 @@ object ContactDiscoveryRefreshV2 {
|
|||||||
systemE164s = inputE164s,
|
systemE164s = inputE164s,
|
||||||
inputPreviousE164s = emptySet(),
|
inputPreviousE164s = emptySet(),
|
||||||
isPartialRefresh = true,
|
isPartialRefresh = true,
|
||||||
useCompat = useCompat,
|
|
||||||
timeoutMs = timeoutMs
|
timeoutMs = timeoutMs
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
@@ -94,10 +92,9 @@ object ContactDiscoveryRefreshV2 {
|
|||||||
systemE164s: Set<String>,
|
systemE164s: Set<String>,
|
||||||
inputPreviousE164s: Set<String>,
|
inputPreviousE164s: Set<String>,
|
||||||
isPartialRefresh: Boolean,
|
isPartialRefresh: Boolean,
|
||||||
useCompat: Boolean,
|
|
||||||
timeoutMs: Long? = null
|
timeoutMs: Long? = null
|
||||||
): ContactDiscovery.RefreshResult {
|
): ContactDiscovery.RefreshResult {
|
||||||
val tag = "refreshInternal-${if (useCompat) "compat" else "v2"}"
|
val tag = "refreshInternal-v2"
|
||||||
val stopwatch = Stopwatch(tag)
|
val stopwatch = Stopwatch(tag)
|
||||||
|
|
||||||
val previousE164s: Set<String> = if (SignalStore.misc().cdsToken != null && !isPartialRefresh) inputPreviousE164s else emptySet()
|
val previousE164s: Set<String> = if (SignalStore.misc().cdsToken != null && !isPartialRefresh) inputPreviousE164s else emptySet()
|
||||||
@@ -127,7 +124,6 @@ object ContactDiscoveryRefreshV2 {
|
|||||||
previousE164s,
|
previousE164s,
|
||||||
newE164s,
|
newE164s,
|
||||||
SignalDatabase.recipients.getAllServiceIdProfileKeyPairs(),
|
SignalDatabase.recipients.getAllServiceIdProfileKeyPairs(),
|
||||||
useCompat,
|
|
||||||
Optional.ofNullable(token),
|
Optional.ofNullable(token),
|
||||||
BuildConfig.CDSI_MRENCLAVE,
|
BuildConfig.CDSI_MRENCLAVE,
|
||||||
timeoutMs
|
timeoutMs
|
||||||
@@ -165,10 +161,6 @@ object ContactDiscoveryRefreshV2 {
|
|||||||
val registeredIds: MutableSet<RecipientId> = mutableSetOf()
|
val registeredIds: MutableSet<RecipientId> = mutableSetOf()
|
||||||
val rewrites: MutableMap<String, String> = mutableMapOf()
|
val rewrites: MutableMap<String, String> = mutableMapOf()
|
||||||
|
|
||||||
if (useCompat && !response.isCompatResponse()) {
|
|
||||||
Log.w(TAG, "Was told to useCompat, but the server responded with a non-compat response! Assuming the server has shut off compat mode.")
|
|
||||||
}
|
|
||||||
|
|
||||||
val transformed: Map<String, CdsV2Result> = response.results.mapValues { entry -> CdsV2Result(entry.value.pni, entry.value.aci.orElse(null)) }
|
val transformed: Map<String, CdsV2Result> = response.results.mapValues { entry -> CdsV2Result(entry.value.pni, entry.value.aci.orElse(null)) }
|
||||||
val fuzzyOutput: OutputResult<CdsV2Result> = FuzzyPhoneNumberHelper.generateOutput(transformed, fuzzyInput)
|
val fuzzyOutput: OutputResult<CdsV2Result> = FuzzyPhoneNumberHelper.generateOutput(transformed, fuzzyInput)
|
||||||
|
|
||||||
@@ -238,13 +230,4 @@ object ContactDiscoveryRefreshV2 {
|
|||||||
val nearestThousand = (this.toDouble() / 1000).roundToInt()
|
val nearestThousand = (this.toDouble() / 1000).roundToInt()
|
||||||
return "~${nearestThousand}k"
|
return "~${nearestThousand}k"
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Responses that respect useCompat will have an ACI for every user. If it doesn't, it means is a PNP response where some accounts may only have PNI's.
|
|
||||||
* There may come a day when we request compat mode but the server refuses to allow it, so we need to be able to detect when that happens to fallback
|
|
||||||
* to the PNP behavior.
|
|
||||||
*/
|
|
||||||
private fun CdsiV2Service.Response.isCompatResponse(): Boolean {
|
|
||||||
return this.results.values.all { it.hasAci() }
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -209,17 +209,15 @@ public class CreateProfileFragment extends LoggingFragment {
|
|||||||
binding.profileDescriptionText.setLinkColor(ContextCompat.getColor(requireContext(), R.color.signal_colorPrimary));
|
binding.profileDescriptionText.setLinkColor(ContextCompat.getColor(requireContext(), R.color.signal_colorPrimary));
|
||||||
binding.profileDescriptionText.setOnLinkClickListener(v -> CommunicationActions.openBrowserLink(requireContext(), getString(R.string.EditProfileFragment__support_link)));
|
binding.profileDescriptionText.setOnLinkClickListener(v -> CommunicationActions.openBrowserLink(requireContext(), getString(R.string.EditProfileFragment__support_link)));
|
||||||
|
|
||||||
if (FeatureFlags.phoneNumberPrivacy()) {
|
getParentFragmentManager().setFragmentResultListener(WhoCanFindMeByPhoneNumberFragment.REQUEST_KEY, getViewLifecycleOwner(), (requestKey, result) -> {
|
||||||
getParentFragmentManager().setFragmentResultListener(WhoCanFindMeByPhoneNumberFragment.REQUEST_KEY, getViewLifecycleOwner(), (requestKey, result) -> {
|
if (WhoCanFindMeByPhoneNumberFragment.REQUEST_KEY.equals(requestKey)) {
|
||||||
if (WhoCanFindMeByPhoneNumberFragment.REQUEST_KEY.equals(requestKey)) {
|
presentWhoCanFindMeDescription(SignalStore.phoneNumberPrivacy().getPhoneNumberDiscoverabilityMode());
|
||||||
presentWhoCanFindMeDescription(SignalStore.phoneNumberPrivacy().getPhoneNumberDiscoverabilityMode());
|
}
|
||||||
}
|
});
|
||||||
});
|
|
||||||
|
|
||||||
binding.whoCanFindMeContainer.setVisibility(View.VISIBLE);
|
binding.whoCanFindMeContainer.setVisibility(View.VISIBLE);
|
||||||
binding.whoCanFindMeContainer.setOnClickListener(v -> SafeNavigation.safeNavigate(Navigation.findNavController(v), CreateProfileFragmentDirections.actionCreateProfileFragmentToPhoneNumberPrivacy()));
|
binding.whoCanFindMeContainer.setOnClickListener(v -> SafeNavigation.safeNavigate(Navigation.findNavController(v), CreateProfileFragmentDirections.actionCreateProfileFragmentToPhoneNumberPrivacy()));
|
||||||
presentWhoCanFindMeDescription(SignalStore.phoneNumberPrivacy().getPhoneNumberDiscoverabilityMode());
|
presentWhoCanFindMeDescription(SignalStore.phoneNumberPrivacy().getPhoneNumberDiscoverabilityMode());
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
binding.finishButton.setOnClickListener(v -> {
|
binding.finishButton.setOnClickListener(v -> {
|
||||||
|
|||||||
@@ -14,7 +14,6 @@ import org.thoughtcrime.securesms.components.settings.DSLSettingsFragment
|
|||||||
import org.thoughtcrime.securesms.components.settings.DSLSettingsText
|
import org.thoughtcrime.securesms.components.settings.DSLSettingsText
|
||||||
import org.thoughtcrime.securesms.components.settings.configure
|
import org.thoughtcrime.securesms.components.settings.configure
|
||||||
import org.thoughtcrime.securesms.databinding.WhoCanFindMeByPhoneNumberFragmentBinding
|
import org.thoughtcrime.securesms.databinding.WhoCanFindMeByPhoneNumberFragmentBinding
|
||||||
import org.thoughtcrime.securesms.util.FeatureFlags
|
|
||||||
import org.thoughtcrime.securesms.util.adapter.mapping.MappingAdapter
|
import org.thoughtcrime.securesms.util.adapter.mapping.MappingAdapter
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -38,8 +37,6 @@ class WhoCanFindMeByPhoneNumberFragment : DSLSettingsFragment(
|
|||||||
private val binding by ViewBinderDelegate(WhoCanFindMeByPhoneNumberFragmentBinding::bind)
|
private val binding by ViewBinderDelegate(WhoCanFindMeByPhoneNumberFragmentBinding::bind)
|
||||||
|
|
||||||
override fun bindAdapter(adapter: MappingAdapter) {
|
override fun bindAdapter(adapter: MappingAdapter) {
|
||||||
require(FeatureFlags.phoneNumberPrivacy())
|
|
||||||
|
|
||||||
lifecycleDisposable += viewModel.state.subscribe {
|
lifecycleDisposable += viewModel.state.subscribe {
|
||||||
adapter.submitList(getConfiguration(it).toMappingModelList())
|
adapter.submitList(getConfiguration(it).toMappingModelList())
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -83,7 +83,6 @@ public final class FeatureFlags {
|
|||||||
private static final String SOFTWARE_AEC_BLOCKLIST_MODELS = "android.calling.softwareAecBlockList";
|
private static final String SOFTWARE_AEC_BLOCKLIST_MODELS = "android.calling.softwareAecBlockList";
|
||||||
private static final String USE_HARDWARE_AEC_IF_OLD = "android.calling.useHardwareAecIfOlderThanApi29";
|
private static final String USE_HARDWARE_AEC_IF_OLD = "android.calling.useHardwareAecIfOlderThanApi29";
|
||||||
private static final String PAYMENTS_COUNTRY_BLOCKLIST = "global.payments.disabledRegions";
|
private static final String PAYMENTS_COUNTRY_BLOCKLIST = "global.payments.disabledRegions";
|
||||||
public static final String PHONE_NUMBER_PRIVACY = "android.pnp";
|
|
||||||
private static final String STORIES_AUTO_DOWNLOAD_MAXIMUM = "android.stories.autoDownloadMaximum";
|
private static final String STORIES_AUTO_DOWNLOAD_MAXIMUM = "android.stories.autoDownloadMaximum";
|
||||||
private static final String TELECOM_MANUFACTURER_ALLOWLIST = "android.calling.telecomAllowList";
|
private static final String TELECOM_MANUFACTURER_ALLOWLIST = "android.calling.telecomAllowList";
|
||||||
private static final String TELECOM_MODEL_BLOCKLIST = "android.calling.telecomModelBlockList";
|
private static final String TELECOM_MODEL_BLOCKLIST = "android.calling.telecomModelBlockList";
|
||||||
@@ -188,7 +187,6 @@ public final class FeatureFlags {
|
|||||||
CALLING_REACTIONS,
|
CALLING_REACTIONS,
|
||||||
NOTIFICATION_THUMBNAIL_BLOCKLIST,
|
NOTIFICATION_THUMBNAIL_BLOCKLIST,
|
||||||
CALLING_RAISE_HAND,
|
CALLING_RAISE_HAND,
|
||||||
PHONE_NUMBER_PRIVACY,
|
|
||||||
USE_ACTIVE_CALL_MANAGER,
|
USE_ACTIVE_CALL_MANAGER,
|
||||||
GIF_SEARCH,
|
GIF_SEARCH,
|
||||||
AUDIO_REMUXING,
|
AUDIO_REMUXING,
|
||||||
@@ -261,7 +259,6 @@ public final class FeatureFlags {
|
|||||||
CALLING_REACTIONS,
|
CALLING_REACTIONS,
|
||||||
NOTIFICATION_THUMBNAIL_BLOCKLIST,
|
NOTIFICATION_THUMBNAIL_BLOCKLIST,
|
||||||
CALLING_RAISE_HAND,
|
CALLING_RAISE_HAND,
|
||||||
PHONE_NUMBER_PRIVACY,
|
|
||||||
VIDEO_RECORD_1X_ZOOM
|
VIDEO_RECORD_1X_ZOOM
|
||||||
);
|
);
|
||||||
|
|
||||||
@@ -369,14 +366,6 @@ public final class FeatureFlags {
|
|||||||
return getString(CLIENT_EXPIRATION, null);
|
return getString(CLIENT_EXPIRATION, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Whether phone number privacy is enabled.
|
|
||||||
* IMPORTANT: This is under active development. Enabling this *will* break your contacts in terrible, irreversible ways.
|
|
||||||
*/
|
|
||||||
public static boolean phoneNumberPrivacy() {
|
|
||||||
return getBoolean(PHONE_NUMBER_PRIVACY, false) || Environment.IS_PNP;
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Whether to use the custom streaming muxer or built in android muxer. */
|
/** Whether to use the custom streaming muxer or built in android muxer. */
|
||||||
public static boolean useStreamingVideoMuxer() {
|
public static boolean useStreamingVideoMuxer() {
|
||||||
return getBoolean(CUSTOM_VIDEO_MUXER, false);
|
return getBoolean(CUSTOM_VIDEO_MUXER, false);
|
||||||
@@ -597,15 +586,6 @@ public final class FeatureFlags {
|
|||||||
return getLong(MAX_ATTACHMENT_SIZE_BYTES, ByteUnit.MEGABYTES.toBytes(100));
|
return getLong(MAX_ATTACHMENT_SIZE_BYTES, ByteUnit.MEGABYTES.toBytes(100));
|
||||||
}
|
}
|
||||||
|
|
||||||
/** True if you should use CDS in compat mode (i.e. request ACI's even if you don't know the access key), otherwise false. */
|
|
||||||
public static boolean cdsCompatMode() {
|
|
||||||
if (phoneNumberPrivacy()) {
|
|
||||||
return false;
|
|
||||||
} else {
|
|
||||||
return !getBoolean(CDS_DISABLE_COMPAT_MODE, false);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Allow the video players to read from the temporary download files for attachments.
|
* Allow the video players to read from the temporary download files for attachments.
|
||||||
* @return whether this functionality is enabled.
|
* @return whether this functionality is enabled.
|
||||||
|
|||||||
@@ -283,8 +283,6 @@ class ContactRecordProcessorTest {
|
|||||||
// GIVEN
|
// GIVEN
|
||||||
val subject = ContactRecordProcessor(ACI_A, PNI_A, E164_A, recipientTable)
|
val subject = ContactRecordProcessor(ACI_A, PNI_A, E164_A, recipientTable)
|
||||||
|
|
||||||
featureFlags.`when`<Boolean> { FeatureFlags.phoneNumberPrivacy() }.thenReturn(true)
|
|
||||||
|
|
||||||
val local = buildRecord(
|
val local = buildRecord(
|
||||||
STORAGE_ID_A,
|
STORAGE_ID_A,
|
||||||
record = ContactRecord(
|
record = ContactRecord(
|
||||||
@@ -317,8 +315,6 @@ class ContactRecordProcessorTest {
|
|||||||
// GIVEN
|
// GIVEN
|
||||||
val subject = ContactRecordProcessor(ACI_A, PNI_A, E164_A, recipientTable)
|
val subject = ContactRecordProcessor(ACI_A, PNI_A, E164_A, recipientTable)
|
||||||
|
|
||||||
featureFlags.`when`<Boolean> { FeatureFlags.phoneNumberPrivacy() }.thenReturn(true)
|
|
||||||
|
|
||||||
val local = buildRecord(
|
val local = buildRecord(
|
||||||
STORAGE_ID_A,
|
STORAGE_ID_A,
|
||||||
record = ContactRecord(
|
record = ContactRecord(
|
||||||
@@ -351,8 +347,6 @@ class ContactRecordProcessorTest {
|
|||||||
// GIVEN
|
// GIVEN
|
||||||
val subject = ContactRecordProcessor(ACI_A, PNI_A, E164_A, recipientTable)
|
val subject = ContactRecordProcessor(ACI_A, PNI_A, E164_A, recipientTable)
|
||||||
|
|
||||||
featureFlags.`when`<Boolean> { FeatureFlags.phoneNumberPrivacy() }.thenReturn(true)
|
|
||||||
|
|
||||||
val local = buildRecord(
|
val local = buildRecord(
|
||||||
STORAGE_ID_A,
|
STORAGE_ID_A,
|
||||||
record = ContactRecord(
|
record = ContactRecord(
|
||||||
@@ -380,40 +374,6 @@ class ContactRecordProcessorTest {
|
|||||||
assertEquals(remote.pni.get(), result.pni.get())
|
assertEquals(remote.pni.get(), result.pni.get())
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
|
||||||
fun `merge, pnpDisabled, pniNotDropped`() {
|
|
||||||
// GIVEN
|
|
||||||
val subject = ContactRecordProcessor(ACI_A, PNI_A, E164_A, recipientTable)
|
|
||||||
|
|
||||||
featureFlags.`when`<Boolean> { FeatureFlags.phoneNumberPrivacy() }.thenReturn(false)
|
|
||||||
|
|
||||||
val local = buildRecord(
|
|
||||||
STORAGE_ID_A,
|
|
||||||
record = ContactRecord(
|
|
||||||
aci = ACI_A.toString(),
|
|
||||||
e164 = E164_A,
|
|
||||||
pni = PNI_A.toStringWithoutPrefix()
|
|
||||||
)
|
|
||||||
)
|
|
||||||
|
|
||||||
val remote = buildRecord(
|
|
||||||
STORAGE_ID_B,
|
|
||||||
record = ContactRecord(
|
|
||||||
aci = ACI_A.toString(),
|
|
||||||
e164 = E164_B,
|
|
||||||
pni = PNI_B.toStringWithoutPrefix()
|
|
||||||
)
|
|
||||||
)
|
|
||||||
|
|
||||||
// WHEN
|
|
||||||
val result = subject.merge(remote, local, TestKeyGenerator(STORAGE_ID_C))
|
|
||||||
|
|
||||||
// THEN
|
|
||||||
assertEquals(remote.aci, result.aci)
|
|
||||||
assertEquals(remote.number.get(), result.number.get())
|
|
||||||
assertEquals(true, result.pni.isPresent)
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun buildRecord(id: StorageId = STORAGE_ID_A, record: ContactRecord): SignalContactRecord {
|
private fun buildRecord(id: StorageId = STORAGE_ID_A, record: ContactRecord): SignalContactRecord {
|
||||||
return SignalContactRecord(id, record)
|
return SignalContactRecord(id, record)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -371,7 +371,6 @@ public class SignalServiceAccountManager {
|
|||||||
public CdsiV2Service.Response getRegisteredUsersWithCdsi(Set<String> previousE164s,
|
public CdsiV2Service.Response getRegisteredUsersWithCdsi(Set<String> previousE164s,
|
||||||
Set<String> newE164s,
|
Set<String> newE164s,
|
||||||
Map<ServiceId, ProfileKey> serviceIds,
|
Map<ServiceId, ProfileKey> serviceIds,
|
||||||
boolean requireAcis,
|
|
||||||
Optional<byte[]> token,
|
Optional<byte[]> token,
|
||||||
String mrEnclave,
|
String mrEnclave,
|
||||||
Long timeoutMs,
|
Long timeoutMs,
|
||||||
@@ -380,7 +379,7 @@ public class SignalServiceAccountManager {
|
|||||||
{
|
{
|
||||||
CdsiAuthResponse auth = pushServiceSocket.getCdsiAuth();
|
CdsiAuthResponse auth = pushServiceSocket.getCdsiAuth();
|
||||||
CdsiV2Service service = new CdsiV2Service(configuration, mrEnclave);
|
CdsiV2Service service = new CdsiV2Service(configuration, mrEnclave);
|
||||||
CdsiV2Service.Request request = new CdsiV2Service.Request(previousE164s, newE164s, serviceIds, requireAcis, token);
|
CdsiV2Service.Request request = new CdsiV2Service.Request(previousE164s, newE164s, serviceIds, token);
|
||||||
Single<ServiceResponse<CdsiV2Service.Response>> single = service.getRegisteredUsers(auth.getUsername(), auth.getPassword(), request, tokenSaver);
|
Single<ServiceResponse<CdsiV2Service.Response>> single = service.getRegisteredUsers(auth.getUsername(), auth.getPassword(), request, tokenSaver);
|
||||||
|
|
||||||
ServiceResponse<CdsiV2Service.Response> serviceResponse;
|
ServiceResponse<CdsiV2Service.Response> serviceResponse;
|
||||||
|
|||||||
@@ -101,8 +101,7 @@ public final class CdsiV2Service {
|
|||||||
.prevE164s(toByteString(previousE164s))
|
.prevE164s(toByteString(previousE164s))
|
||||||
.newE164s(toByteString(newE164s))
|
.newE164s(toByteString(newE164s))
|
||||||
.discardE164s(toByteString(removedE164s))
|
.discardE164s(toByteString(removedE164s))
|
||||||
.aciUakPairs(toByteString(request.serviceIds))
|
.aciUakPairs(toByteString(request.serviceIds));
|
||||||
.returnAcisWithoutUaks(request.requireAcis);
|
|
||||||
|
|
||||||
if (request.token != null) {
|
if (request.token != null) {
|
||||||
builder.token(ByteString.of(request.token));
|
builder.token(ByteString.of(request.token));
|
||||||
@@ -155,11 +154,9 @@ public final class CdsiV2Service {
|
|||||||
|
|
||||||
final Map<ServiceId, ProfileKey> serviceIds;
|
final Map<ServiceId, ProfileKey> serviceIds;
|
||||||
|
|
||||||
final boolean requireAcis;
|
|
||||||
|
|
||||||
final byte[] token;
|
final byte[] token;
|
||||||
|
|
||||||
public Request(Set<String> previousE164s, Set<String> newE164s, Map<ServiceId, ProfileKey> serviceIds, boolean requireAcis, Optional<byte[]> token) {
|
public Request(Set<String> previousE164s, Set<String> newE164s, Map<ServiceId, ProfileKey> serviceIds, Optional<byte[]> token) {
|
||||||
if (previousE164s.size() > 0 && !token.isPresent()) {
|
if (previousE164s.size() > 0 && !token.isPresent()) {
|
||||||
throw new IllegalArgumentException("You must have a token if you have previousE164s!");
|
throw new IllegalArgumentException("You must have a token if you have previousE164s!");
|
||||||
}
|
}
|
||||||
@@ -168,7 +165,6 @@ public final class CdsiV2Service {
|
|||||||
this.newE164s = newE164s;
|
this.newE164s = newE164s;
|
||||||
this.removedE164s = Collections.emptySet();
|
this.removedE164s = Collections.emptySet();
|
||||||
this.serviceIds = serviceIds;
|
this.serviceIds = serviceIds;
|
||||||
this.requireAcis = requireAcis;
|
|
||||||
this.token = token.orElse(null);
|
this.token = token.orElse(null);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user