mirror of
https://github.com/signalapp/Signal-Android.git
synced 2025-12-23 20:48:43 +00:00
Add 10s timeout to user facing CDSI requests.
This commit is contained in:
committed by
Greyson Parrelli
parent
8d20669e46
commit
36fc9aa82a
@@ -59,6 +59,7 @@ import java.io.IOException;
|
|||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Objects;
|
import java.util.Objects;
|
||||||
import java.util.Optional;
|
import java.util.Optional;
|
||||||
|
import java.util.concurrent.TimeUnit;
|
||||||
import java.util.function.Consumer;
|
import java.util.function.Consumer;
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
import java.util.stream.Stream;
|
import java.util.stream.Stream;
|
||||||
@@ -121,7 +122,7 @@ public class NewConversationActivity extends ContactSelectionActivity
|
|||||||
if (!resolved.isRegistered() || !resolved.hasServiceId()) {
|
if (!resolved.isRegistered() || !resolved.hasServiceId()) {
|
||||||
Log.i(TAG, "[onContactSelected] Not registered or no UUID. Doing a directory refresh.");
|
Log.i(TAG, "[onContactSelected] Not registered or no UUID. Doing a directory refresh.");
|
||||||
try {
|
try {
|
||||||
ContactDiscovery.refresh(this, resolved, false);
|
ContactDiscovery.refresh(this, resolved, false, TimeUnit.SECONDS.toMillis(10));
|
||||||
resolved = Recipient.resolved(resolved.getId());
|
resolved = Recipient.resolved(resolved.getId());
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
Log.w(TAG, "[onContactSelected] Failed to refresh directory for new contact.");
|
Log.w(TAG, "[onContactSelected] Failed to refresh directory for new contact.");
|
||||||
|
|||||||
@@ -25,6 +25,7 @@ import org.thoughtcrime.securesms.util.views.SimpleProgressDialog
|
|||||||
import java.io.IOException
|
import java.io.IOException
|
||||||
import java.util.Optional
|
import java.util.Optional
|
||||||
import java.util.function.Consumer
|
import java.util.function.Consumer
|
||||||
|
import kotlin.time.Duration.Companion.seconds
|
||||||
|
|
||||||
class NewCallActivity : ContactSelectionActivity(), ContactSelectionListFragment.NewCallCallback {
|
class NewCallActivity : ContactSelectionActivity(), ContactSelectionListFragment.NewCallCallback {
|
||||||
|
|
||||||
@@ -49,7 +50,7 @@ class NewCallActivity : ContactSelectionActivity(), ContactSelectionListFragment
|
|||||||
if (!resolved.isRegistered || !resolved.hasServiceId()) {
|
if (!resolved.isRegistered || !resolved.hasServiceId()) {
|
||||||
Log.i(TAG, "[onContactSelected] Not registered or no UUID. Doing a directory refresh.")
|
Log.i(TAG, "[onContactSelected] Not registered or no UUID. Doing a directory refresh.")
|
||||||
resolved = try {
|
resolved = try {
|
||||||
refresh(this, resolved, false)
|
refresh(this, resolved, false, 10.seconds.inWholeMilliseconds)
|
||||||
Recipient.resolved(resolved.id)
|
Recipient.resolved(resolved.id)
|
||||||
} catch (e: IOException) {
|
} catch (e: IOException) {
|
||||||
Log.w(TAG, "[onContactSelected] Failed to refresh directory for new contact.")
|
Log.w(TAG, "[onContactSelected] Failed to refresh directory for new contact.")
|
||||||
|
|||||||
@@ -91,14 +91,15 @@ object ContactDiscovery {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@JvmStatic
|
@JvmStatic
|
||||||
|
@JvmOverloads
|
||||||
@Throws(IOException::class)
|
@Throws(IOException::class)
|
||||||
@WorkerThread
|
@WorkerThread
|
||||||
fun refresh(context: Context, recipient: Recipient, notifyOfNewUsers: Boolean): RecipientTable.RegisteredState {
|
fun refresh(context: Context, recipient: Recipient, notifyOfNewUsers: Boolean, timeoutMs: Long? = null): RecipientTable.RegisteredState {
|
||||||
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), useCompat = !FeatureFlags.phoneNumberPrivacy(), ignoreResults = false)
|
ContactDiscoveryRefreshV2.refresh(context, listOf(recipient), useCompat = !FeatureFlags.phoneNumberPrivacy(), ignoreResults = false, timeoutMs = timeoutMs)
|
||||||
},
|
},
|
||||||
removeSystemContactLinksIfMissing = false,
|
removeSystemContactLinksIfMissing = false,
|
||||||
notifyOfNewUsers = notifyOfNewUsers
|
notifyOfNewUsers = notifyOfNewUsers
|
||||||
|
|||||||
@@ -49,7 +49,7 @@ object ContactDiscoveryRefreshV2 {
|
|||||||
@WorkerThread
|
@WorkerThread
|
||||||
@Synchronized
|
@Synchronized
|
||||||
@JvmStatic
|
@JvmStatic
|
||||||
fun refreshAll(context: Context, useCompat: Boolean, ignoreResults: Boolean): ContactDiscovery.RefreshResult {
|
fun refreshAll(context: Context, useCompat: Boolean, ignoreResults: Boolean, 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()
|
||||||
|
|
||||||
@@ -59,7 +59,8 @@ object ContactDiscoveryRefreshV2 {
|
|||||||
inputPreviousE164s = SignalDatabase.cds.getAllE164s(),
|
inputPreviousE164s = SignalDatabase.cds.getAllE164s(),
|
||||||
isPartialRefresh = false,
|
isPartialRefresh = false,
|
||||||
useCompat = useCompat,
|
useCompat = useCompat,
|
||||||
ignoreResults = ignoreResults
|
ignoreResults = ignoreResults,
|
||||||
|
timeoutMs = timeoutMs
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -67,14 +68,14 @@ object ContactDiscoveryRefreshV2 {
|
|||||||
@WorkerThread
|
@WorkerThread
|
||||||
@Synchronized
|
@Synchronized
|
||||||
@JvmStatic
|
@JvmStatic
|
||||||
fun refresh(context: Context, inputRecipients: List<Recipient>, useCompat: Boolean, ignoreResults: Boolean): ContactDiscovery.RefreshResult {
|
fun refresh(context: Context, inputRecipients: List<Recipient>, useCompat: Boolean, ignoreResults: Boolean, 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, ignoreResults = ignoreResults)
|
val fullResult: ContactDiscovery.RefreshResult = refreshAll(context, useCompat = useCompat, ignoreResults = ignoreResults, timeoutMs = timeoutMs)
|
||||||
val inputIds: Set<RecipientId> = recipients.map { it.id }.toSet()
|
val inputIds: Set<RecipientId> = recipients.map { it.id }.toSet()
|
||||||
|
|
||||||
ContactDiscovery.RefreshResult(
|
ContactDiscovery.RefreshResult(
|
||||||
@@ -88,7 +89,8 @@ object ContactDiscoveryRefreshV2 {
|
|||||||
inputPreviousE164s = emptySet(),
|
inputPreviousE164s = emptySet(),
|
||||||
isPartialRefresh = true,
|
isPartialRefresh = true,
|
||||||
useCompat = useCompat,
|
useCompat = useCompat,
|
||||||
ignoreResults = ignoreResults
|
ignoreResults = ignoreResults,
|
||||||
|
timeoutMs = timeoutMs
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -100,7 +102,8 @@ object ContactDiscoveryRefreshV2 {
|
|||||||
inputPreviousE164s: Set<String>,
|
inputPreviousE164s: Set<String>,
|
||||||
isPartialRefresh: Boolean,
|
isPartialRefresh: Boolean,
|
||||||
useCompat: Boolean,
|
useCompat: Boolean,
|
||||||
ignoreResults: Boolean
|
ignoreResults: Boolean,
|
||||||
|
timeoutMs: Long? = null
|
||||||
): ContactDiscovery.RefreshResult {
|
): ContactDiscovery.RefreshResult {
|
||||||
val tag = "refreshInternal-${if (useCompat) "compat" else "v2"}"
|
val tag = "refreshInternal-${if (useCompat) "compat" else "v2"}"
|
||||||
val stopwatch = Stopwatch(tag)
|
val stopwatch = Stopwatch(tag)
|
||||||
@@ -134,7 +137,8 @@ object ContactDiscoveryRefreshV2 {
|
|||||||
SignalDatabase.recipients.getAllServiceIdProfileKeyPairs(),
|
SignalDatabase.recipients.getAllServiceIdProfileKeyPairs(),
|
||||||
useCompat,
|
useCompat,
|
||||||
Optional.ofNullable(token),
|
Optional.ofNullable(token),
|
||||||
BuildConfig.CDSI_MRENCLAVE
|
BuildConfig.CDSI_MRENCLAVE,
|
||||||
|
timeoutMs
|
||||||
) { tokenToSave ->
|
) { tokenToSave ->
|
||||||
stopwatch.split("network-pre-token")
|
stopwatch.split("network-pre-token")
|
||||||
if (!isPartialRefresh) {
|
if (!isPartialRefresh) {
|
||||||
|
|||||||
@@ -723,7 +723,7 @@ public class ConversationParentFragment extends Fragment
|
|||||||
case ADD_CONTACT:
|
case ADD_CONTACT:
|
||||||
SimpleTask.run(() -> {
|
SimpleTask.run(() -> {
|
||||||
try {
|
try {
|
||||||
ContactDiscovery.refresh(requireContext(), recipient.get(), false);
|
ContactDiscovery.refresh(requireContext(), recipient.get(), false, TimeUnit.SECONDS.toMillis(10));
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
Log.w(TAG, "Failed to refresh user after adding to contacts.");
|
Log.w(TAG, "Failed to refresh user after adding to contacts.");
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -33,6 +33,7 @@ import java.io.IOException;
|
|||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Optional;
|
import java.util.Optional;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
import java.util.concurrent.TimeUnit;
|
||||||
import java.util.function.Consumer;
|
import java.util.function.Consumer;
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
@@ -160,7 +161,7 @@ public class CreateGroupActivity extends ContactSelectionActivity {
|
|||||||
|
|
||||||
for (Recipient recipient : registeredChecks) {
|
for (Recipient recipient : registeredChecks) {
|
||||||
try {
|
try {
|
||||||
ContactDiscovery.refresh(this, recipient, false);
|
ContactDiscovery.refresh(this, recipient, false, TimeUnit.SECONDS.toMillis(10));
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
Log.w(TAG, "Failed to refresh registered status for " + recipient.getId(), e);
|
Log.w(TAG, "Failed to refresh registered status for " + recipient.getId(), e);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -49,6 +49,7 @@ import org.whispersystems.signalservice.api.push.ServiceId;
|
|||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.util.Optional;
|
import java.util.Optional;
|
||||||
|
import java.util.concurrent.TimeUnit;
|
||||||
|
|
||||||
public class CommunicationActions {
|
public class CommunicationActions {
|
||||||
|
|
||||||
@@ -303,7 +304,7 @@ public class CommunicationActions {
|
|||||||
|
|
||||||
if (!recipient.isRegistered() || !recipient.hasServiceId()) {
|
if (!recipient.isRegistered() || !recipient.hasServiceId()) {
|
||||||
try {
|
try {
|
||||||
ContactDiscovery.refresh(activity, recipient, false);
|
ContactDiscovery.refresh(activity, recipient, false, TimeUnit.SECONDS.toMillis(10));
|
||||||
recipient = Recipient.resolved(recipient.getId());
|
recipient = Recipient.resolved(recipient.getId());
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
Log.w(TAG, "[handlePotentialSignalMeUrl] Failed to refresh directory for new contact.");
|
Log.w(TAG, "[handlePotentialSignalMeUrl] Failed to refresh directory for new contact.");
|
||||||
|
|||||||
@@ -390,6 +390,7 @@ public class SignalServiceAccountManager {
|
|||||||
boolean requireAcis,
|
boolean requireAcis,
|
||||||
Optional<byte[]> token,
|
Optional<byte[]> token,
|
||||||
String mrEnclave,
|
String mrEnclave,
|
||||||
|
Long timeoutMs,
|
||||||
Consumer<byte[]> tokenSaver)
|
Consumer<byte[]> tokenSaver)
|
||||||
throws IOException
|
throws IOException
|
||||||
{
|
{
|
||||||
@@ -400,11 +401,20 @@ public class SignalServiceAccountManager {
|
|||||||
|
|
||||||
ServiceResponse<CdsiV2Service.Response> serviceResponse;
|
ServiceResponse<CdsiV2Service.Response> serviceResponse;
|
||||||
try {
|
try {
|
||||||
serviceResponse = single.blockingGet();
|
if (timeoutMs == null) {
|
||||||
|
serviceResponse = single
|
||||||
|
.blockingGet();
|
||||||
|
} else {
|
||||||
|
serviceResponse = single
|
||||||
|
.timeout(timeoutMs, TimeUnit.MILLISECONDS)
|
||||||
|
.blockingGet();
|
||||||
|
}
|
||||||
} catch (RuntimeException e) {
|
} catch (RuntimeException e) {
|
||||||
Throwable cause = e.getCause();
|
Throwable cause = e.getCause();
|
||||||
if (cause instanceof InterruptedException) {
|
if (cause instanceof InterruptedException) {
|
||||||
throw new IOException("Interrupted", cause);
|
throw new IOException("Interrupted", cause);
|
||||||
|
} else if (cause instanceof TimeoutException) {
|
||||||
|
throw new IOException("Timed out");
|
||||||
} else {
|
} else {
|
||||||
throw e;
|
throw e;
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user