From cbee11a2f56bf718396e46d6d87ca0dc59ab8561 Mon Sep 17 00:00:00 2001 From: Stephen Paul Weber Date: Sat, 24 Jun 2023 20:19:24 -0500 Subject: [PATCH] Allow specifying a timeout for an iq send --- .../services/XmppConnectionService.java | 6 ++++- .../conversations/xmpp/XmppConnection.java | 24 +++++++++++++++++-- 2 files changed, 27 insertions(+), 3 deletions(-) diff --git a/src/main/java/eu/siacs/conversations/services/XmppConnectionService.java b/src/main/java/eu/siacs/conversations/services/XmppConnectionService.java index dc73c23fefa4b7fce79a7eed013a66788262795f..28c128254fd806a88a2a5bd76daf621736a8ee9d 100644 --- a/src/main/java/eu/siacs/conversations/services/XmppConnectionService.java +++ b/src/main/java/eu/siacs/conversations/services/XmppConnectionService.java @@ -4706,9 +4706,13 @@ public class XmppConnectionService extends Service { } public void sendIqPacket(final Account account, final IqPacket packet, final OnIqPacketReceived callback) { + sendIqPacket(account, packet, callback, null); + } + + public void sendIqPacket(final Account account, final IqPacket packet, final OnIqPacketReceived callback, Long timeout) { final XmppConnection connection = account.getXmppConnection(); if (connection != null) { - connection.sendIqPacket(packet, callback); + connection.sendIqPacket(packet, callback, timeout); } else if (callback != null) { callback.onIqPacketReceived(account, new IqPacket(IqPacket.TYPE.TIMEOUT)); } diff --git a/src/main/java/eu/siacs/conversations/xmpp/XmppConnection.java b/src/main/java/eu/siacs/conversations/xmpp/XmppConnection.java index a9db21ba7c12399d0602f57870729a485738cd9f..b8357806134e28a2479f832d0a4b10f2b64b81a6 100644 --- a/src/main/java/eu/siacs/conversations/xmpp/XmppConnection.java +++ b/src/main/java/eu/siacs/conversations/xmpp/XmppConnection.java @@ -47,6 +47,8 @@ import java.util.List; import java.util.Map.Entry; import java.util.Set; import java.util.concurrent.CountDownLatch; +import java.util.concurrent.Executors; +import java.util.concurrent.ScheduledExecutorService; import java.util.concurrent.TimeUnit; import java.util.concurrent.atomic.AtomicBoolean; import java.util.concurrent.atomic.AtomicInteger; @@ -190,6 +192,7 @@ public class XmppConnection implements Runnable { private String verifiedHostname = null; private volatile Thread mThread; private CountDownLatch mStreamCountDownLatch; + private static ScheduledExecutorService SCHEDULER = Executors.newScheduledThreadPool(1); public XmppConnection(final Account account, final XmppConnectionService service) { this.account = account; @@ -2243,12 +2246,20 @@ public class XmppConnection implements Runnable { } public String sendIqPacket(final IqPacket packet, final OnIqPacketReceived callback) { + return sendIqPacket(packet, callback, null); + } + + public String sendIqPacket(final IqPacket packet, final OnIqPacketReceived callback, Long timeout) { packet.setFrom(account.getJid()); - return this.sendUnmodifiedIqPacket(packet, callback, false); + return this.sendUnmodifiedIqPacket(packet, callback, false, timeout); + } + + public String sendUnmodifiedIqPacket(final IqPacket packet, final OnIqPacketReceived callback, boolean force) { + return sendUnmodifiedIqPacket(packet, callback, force, null); } public synchronized String sendUnmodifiedIqPacket( - final IqPacket packet, final OnIqPacketReceived callback, boolean force) { + final IqPacket packet, final OnIqPacketReceived callback, boolean force, Long timeout) { if (packet.getId() == null) { packet.setAttribute("id", nextRandomId()); } @@ -2258,6 +2269,15 @@ public class XmppConnection implements Runnable { } } this.sendPacket(packet, force); + if (timeout != null) { + SCHEDULER.schedule(() -> { + synchronized (this.packetCallbacks) { + final IqPacket failurePacket = new IqPacket(IqPacket.TYPE.TIMEOUT); + final Pair removedCallback = packetCallbacks.remove(packet.getId()); + if (removedCallback != null) removedCallback.second.onIqPacketReceived(account, failurePacket); + } + }, timeout, TimeUnit.SECONDS); + } return packet.getId(); }