put offline messages purge into manager

Daniel Gultsch created

Change summary

src/main/java/eu/siacs/conversations/generator/IqGenerator.java               | 20 
src/main/java/eu/siacs/conversations/xmpp/Managers.java                       |  2 
src/main/java/eu/siacs/conversations/xmpp/XmppConnection.java                 |  5 
src/main/java/eu/siacs/conversations/xmpp/manager/OfflineMessagesManager.java | 30 
src/main/java/im/conversations/android/xmpp/model/offline/Offline.java        | 12 
src/main/java/im/conversations/android/xmpp/model/offline/Purge.java          | 12 
src/main/java/im/conversations/android/xmpp/model/offline/package-info.java   |  5 
src/main/java/im/conversations/android/xmpp/processor/BindProcessor.java      | 27 
8 files changed, 80 insertions(+), 33 deletions(-)

Detailed changes

src/main/java/eu/siacs/conversations/generator/IqGenerator.java 🔗

@@ -5,7 +5,6 @@ import android.util.Base64;
 import android.util.Log;
 import eu.siacs.conversations.Config;
 import eu.siacs.conversations.crypto.axolotl.AxolotlService;
-import eu.siacs.conversations.entities.Account;
 import eu.siacs.conversations.entities.Conversation;
 import eu.siacs.conversations.services.MessageArchiveService;
 import eu.siacs.conversations.services.XmppConnectionService;
@@ -30,12 +29,6 @@ public class IqGenerator extends AbstractGenerator {
         super(service);
     }
 
-    public static Iq purgeOfflineMessages() {
-        final Iq packet = new Iq(Iq.Type.SET);
-        packet.addChild("offline", Namespace.FLEXIBLE_OFFLINE_MESSAGE_RETRIEVAL).addChild("purge");
-        return packet;
-    }
-
     protected Iq publish(final String node, final Element item, final Bundle options) {
         final var packet = new Iq(Iq.Type.SET);
         final Element pubsub = packet.addChild("pubsub", Namespace.PUBSUB);
@@ -217,19 +210,6 @@ public class IqGenerator extends AbstractGenerator {
         return packet;
     }
 
-    public static Iq generateCreateAccountWithCaptcha(
-            final Account account, final String id, final Data data) {
-        final Iq register = new Iq(Iq.Type.SET);
-        register.setFrom(account.getJid().asBareJid());
-        register.setTo(account.getDomain());
-        register.setId(id);
-        Element query = register.query(Namespace.REGISTER);
-        if (data != null) {
-            query.addChild(data);
-        }
-        return register;
-    }
-
     public Iq pushTokenToAppServer(Jid appServer, String token, String deviceId) {
         return pushTokenToAppServer(appServer, token, deviceId, null);
     }

src/main/java/eu/siacs/conversations/xmpp/Managers.java 🔗

@@ -15,6 +15,7 @@ import eu.siacs.conversations.xmpp.manager.HttpUploadManager;
 import eu.siacs.conversations.xmpp.manager.LegacyBookmarkManager;
 import eu.siacs.conversations.xmpp.manager.MessageDisplayedSynchronizationManager;
 import eu.siacs.conversations.xmpp.manager.NickManager;
+import eu.siacs.conversations.xmpp.manager.OfflineMessagesManager;
 import eu.siacs.conversations.xmpp.manager.PepManager;
 import eu.siacs.conversations.xmpp.manager.PingManager;
 import eu.siacs.conversations.xmpp.manager.PresenceManager;
@@ -48,6 +49,7 @@ public class Managers {
                         MessageDisplayedSynchronizationManager.class,
                         new MessageDisplayedSynchronizationManager(context, connection))
                 .put(NickManager.class, new NickManager(context, connection))
+                .put(OfflineMessagesManager.class, new OfflineMessagesManager(context, connection))
                 .put(PepManager.class, new PepManager(context, connection))
                 .put(PingManager.class, new PingManager(context, connection))
                 .put(PresenceManager.class, new PresenceManager(context, connection))

src/main/java/eu/siacs/conversations/xmpp/XmppConnection.java 🔗

@@ -2969,11 +2969,6 @@ public class XmppConnection implements Runnable {
             return hasDiscoFeature(account.getDomain(), Namespace.REPORTING);
         }
 
-        public boolean flexibleOfflineMessageRetrieval() {
-            return hasDiscoFeature(
-                    account.getDomain(), Namespace.FLEXIBLE_OFFLINE_MESSAGE_RETRIEVAL);
-        }
-
         public boolean sm() {
             return streamId != null
                     || (connection.streamFeatures != null

src/main/java/eu/siacs/conversations/xmpp/manager/OfflineMessagesManager.java 🔗

@@ -0,0 +1,30 @@
+package eu.siacs.conversations.xmpp.manager;
+
+import android.content.Context;
+import com.google.common.util.concurrent.Futures;
+import com.google.common.util.concurrent.ListenableFuture;
+import com.google.common.util.concurrent.MoreExecutors;
+import eu.siacs.conversations.xml.Namespace;
+import eu.siacs.conversations.xmpp.XmppConnection;
+import im.conversations.android.xmpp.model.offline.Offline;
+import im.conversations.android.xmpp.model.offline.Purge;
+import im.conversations.android.xmpp.model.stanza.Iq;
+
+public class OfflineMessagesManager extends AbstractManager {
+
+    public OfflineMessagesManager(Context context, XmppConnection connection) {
+        super(context, connection);
+    }
+
+    public ListenableFuture<Void> purge() {
+        final var iq = new Iq(Iq.Type.SET);
+        iq.addExtension(new Offline()).addExtension(new Purge());
+        final var future = connection.sendIqPacket(iq);
+        return Futures.transform(future, result -> null, MoreExecutors.directExecutor());
+    }
+
+    public boolean hasFeature() {
+        return getManager(DiscoManager.class)
+                .hasServerFeature(Namespace.FLEXIBLE_OFFLINE_MESSAGE_RETRIEVAL);
+    }
+}

src/main/java/im/conversations/android/xmpp/model/offline/Offline.java 🔗

@@ -0,0 +1,12 @@
+package im.conversations.android.xmpp.model.offline;
+
+import im.conversations.android.annotation.XmlElement;
+import im.conversations.android.xmpp.model.Extension;
+
+@XmlElement
+public class Offline extends Extension {
+
+    public Offline() {
+        super(Offline.class);
+    }
+}

src/main/java/im/conversations/android/xmpp/model/offline/Purge.java 🔗

@@ -0,0 +1,12 @@
+package im.conversations.android.xmpp.model.offline;
+
+import im.conversations.android.annotation.XmlElement;
+import im.conversations.android.xmpp.model.Extension;
+
+@XmlElement
+public class Purge extends Extension {
+
+    public Purge() {
+        super(Purge.class);
+    }
+}

src/main/java/im/conversations/android/xmpp/processor/BindProcessor.java 🔗

@@ -1,10 +1,13 @@
 package im.conversations.android.xmpp.processor;
 
 import android.util.Log;
+import androidx.annotation.NonNull;
 import com.google.common.base.Strings;
+import com.google.common.util.concurrent.FutureCallback;
+import com.google.common.util.concurrent.Futures;
+import com.google.common.util.concurrent.MoreExecutors;
 import eu.siacs.conversations.Config;
 import eu.siacs.conversations.entities.Account;
-import eu.siacs.conversations.generator.IqGenerator;
 import eu.siacs.conversations.services.XmppConnectionService;
 import eu.siacs.conversations.xmpp.XmppConnection;
 import eu.siacs.conversations.xmpp.manager.BookmarkManager;
@@ -12,9 +15,9 @@ import eu.siacs.conversations.xmpp.manager.HttpUploadManager;
 import eu.siacs.conversations.xmpp.manager.LegacyBookmarkManager;
 import eu.siacs.conversations.xmpp.manager.MessageDisplayedSynchronizationManager;
 import eu.siacs.conversations.xmpp.manager.NickManager;
+import eu.siacs.conversations.xmpp.manager.OfflineMessagesManager;
 import eu.siacs.conversations.xmpp.manager.PrivateStorageManager;
 import eu.siacs.conversations.xmpp.manager.RosterManager;
-import im.conversations.android.xmpp.model.stanza.Iq;
 
 public class BindProcessor extends XmppConnection.Delegate implements Runnable {
 
@@ -85,22 +88,30 @@ public class BindProcessor extends XmppConnection.Delegate implements Runnable {
         } else {
             Log.d(Config.LOGTAG, account.getJid() + ": server has no support for mds");
         }
+        final var offlineManager = getManager(OfflineMessagesManager.class);
         final boolean bind2 = features.bind2();
-        final boolean flexible = features.flexibleOfflineMessageRetrieval();
+        final boolean flexible = offlineManager.hasFeature();
         final boolean catchup = service.getMessageArchiveService().inCatchup(account);
         final boolean trackOfflineMessageRetrieval;
         if (!bind2 && flexible && catchup && connection.isMamPreferenceAlways()) {
             trackOfflineMessageRetrieval = false;
-            connection.sendIqPacket(
-                    IqGenerator.purgeOfflineMessages(),
-                    (packet) -> {
-                        if (packet.getType() == Iq.Type.RESULT) {
+            Futures.addCallback(
+                    offlineManager.purge(),
+                    new FutureCallback<Void>() {
+                        @Override
+                        public void onSuccess(Void result) {
                             Log.d(
                                     Config.LOGTAG,
                                     account.getJid().asBareJid()
                                             + ": successfully purged offline messages");
                         }
-                    });
+
+                        @Override
+                        public void onFailure(@NonNull Throwable t) {
+                            Log.d(Config.LOGTAG, "could not purge offline messages", t);
+                        }
+                    },
+                    MoreExecutors.directExecutor());
         } else {
             trackOfflineMessageRetrieval = true;
         }