add receipt manager and process receipt requests

This commit is contained in:
Daniel Gultsch 2023-02-07 14:59:29 +01:00
parent 870393df8e
commit bed6b07bdd
No known key found for this signature in database
GPG key ID: F43D18AD2A0982C2
11 changed files with 154 additions and 16 deletions

View file

@ -14,6 +14,7 @@ import im.conversations.android.xmpp.manager.NickManager;
import im.conversations.android.xmpp.manager.PepManager;
import im.conversations.android.xmpp.manager.PresenceManager;
import im.conversations.android.xmpp.manager.PubSubManager;
import im.conversations.android.xmpp.manager.ReceiptManager;
import im.conversations.android.xmpp.manager.RosterManager;
public final class Managers {
@ -33,6 +34,7 @@ public final class Managers {
.put(PepManager.class, new PepManager(context, connection))
.put(PresenceManager.class, new PresenceManager(context, connection))
.put(PubSubManager.class, new PubSubManager(context, connection))
.put(ReceiptManager.class, new ReceiptManager(context, connection))
.put(RosterManager.class, new RosterManager(context, connection))
.build();
}

View file

@ -20,7 +20,8 @@ public class CarbonsManager extends AbstractManager {
public CarbonsManager(Context context, XmppConnection connection) {
super(context, connection);
this.messageProcessor = new MessageProcessor(context, connection, false);
this.messageProcessor =
new MessageProcessor(context, connection, MessageProcessor.Level.CARBON);
}
public void enable() {

View file

@ -0,0 +1,43 @@
package im.conversations.android.xmpp.manager;
import android.content.Context;
import com.google.common.base.Strings;
import eu.siacs.conversations.xmpp.Jid;
import im.conversations.android.xmpp.XmppConnection;
import im.conversations.android.xmpp.model.DeliveryReceiptRequest;
import im.conversations.android.xmpp.model.markers.Markable;
import im.conversations.android.xmpp.model.receipts.Received;
import im.conversations.android.xmpp.model.receipts.Request;
import im.conversations.android.xmpp.model.stanza.Message;
import java.util.Collection;
public class ReceiptManager extends AbstractManager {
public ReceiptManager(Context context, XmppConnection connection) {
super(context, connection);
}
public void received(
final Jid from,
final String id,
Collection<DeliveryReceiptRequest> deliveryReceiptRequests) {
if (deliveryReceiptRequests.isEmpty() || Strings.isNullOrEmpty(id)) {
return;
}
// TODO check roster
final Message response = new Message();
response.setTo(from);
for (final DeliveryReceiptRequest request : deliveryReceiptRequests) {
if (request instanceof Request) {
final var received = response.addExtension(new Received());
received.setId(id);
} else if (request instanceof Markable) {
final var received =
response.addExtension(
new im.conversations.android.xmpp.model.markers.Received());
received.setId(id);
}
}
connection.sendMessagePacket(response);
}
}

View file

@ -0,0 +1,8 @@
package im.conversations.android.xmpp.model;
public abstract class DeliveryReceiptRequest extends Extension {
protected DeliveryReceiptRequest(Class<? extends Extension> clazz) {
super(clazz);
}
}

View file

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

View file

@ -0,0 +1,16 @@
package im.conversations.android.xmpp.model.markers;
import im.conversations.android.annotation.XmlElement;
import im.conversations.android.xmpp.model.Extension;
@XmlElement
public class Received extends Extension {
public Received() {
super(Received.class);
}
public void setId(String id) {
this.setAttribute("id", id);
}
}

View file

@ -0,0 +1,5 @@
@XmlPackage(namespace = Namespace.CHAT_MARKERS)
package im.conversations.android.xmpp.model.markers;
import eu.siacs.conversations.xml.Namespace;
import im.conversations.android.annotation.XmlPackage;

View file

@ -0,0 +1,16 @@
package im.conversations.android.xmpp.model.receipts;
import im.conversations.android.annotation.XmlElement;
import im.conversations.android.xmpp.model.Extension;
@XmlElement
public class Received extends Extension {
public Received() {
super(Received.class);
}
public void setId(String id) {
this.setAttribute("id", id);
}
}

View file

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

View file

@ -0,0 +1,5 @@
@XmlPackage(namespace = Namespace.DELIVERY_RECEIPTS)
package im.conversations.android.xmpp.model.receipts;
import eu.siacs.conversations.xml.Namespace;
import im.conversations.android.annotation.XmlPackage;

View file

@ -1,10 +1,12 @@
package im.conversations.android.xmpp.processor;
import android.content.Context;
import com.google.common.base.Strings;
import eu.siacs.conversations.xmpp.Jid;
import im.conversations.android.xmpp.XmppConnection;
import im.conversations.android.xmpp.manager.CarbonsManager;
import im.conversations.android.xmpp.manager.PubSubManager;
import im.conversations.android.xmpp.manager.ReceiptManager;
import im.conversations.android.xmpp.model.DeliveryReceiptRequest;
import im.conversations.android.xmpp.model.carbons.Received;
import im.conversations.android.xmpp.model.carbons.Sent;
import im.conversations.android.xmpp.model.pubsub.event.Event;
@ -17,50 +19,66 @@ public class MessageProcessor extends XmppConnection.Delegate implements Consume
private static final Logger LOGGER = LoggerFactory.getLogger(MessageProcessor.class);
private final boolean isRoot;
private final Level level;
public MessageProcessor(final Context context, final XmppConnection connection) {
this(context, connection, true);
this(context, connection, Level.ROOT);
}
public MessageProcessor(
final Context context, final XmppConnection connection, final boolean isRoot) {
final Context context, final XmppConnection connection, final Level level) {
super(context, connection);
this.isRoot = isRoot;
this.level = level;
}
@Override
public void accept(final Message message) {
if (isRoot && connection.fromServer(message) && message.hasExtension(Received.class)) {
if (isRoot() && connection.fromServer(message) && message.hasExtension(Received.class)) {
getManager(CarbonsManager.class).handleReceived(message.getExtension(Received.class));
return;
}
if (isRoot && connection.fromServer(message) && message.hasExtension(Sent.class)) {
if (isRoot() && connection.fromServer(message) && message.hasExtension(Sent.class)) {
getManager(CarbonsManager.class).handleSent(message.getExtension(Sent.class));
return;
}
if (isRoot && message.hasExtension(Event.class)) {
if (isRoot() && message.hasExtension(Event.class)) {
getManager(PubSubManager.class).handleEvent(message);
return;
}
final String body = message.getBody();
if (!Strings.isNullOrEmpty(body)) {
LOGGER.info("'{}' from {}", body, message.getFrom());
}
final String id = message.getId();
final Jid from = message.getFrom();
LOGGER.info("Message received {}", message.getExtensionIds());
// TODO process receipt requests (184 + 333)
// TODO only do this if transformation was successful or nothing to transform
if (isRealtimeProcessor()) {
final var requests = message.getExtensions(DeliveryReceiptRequest.class);
getManager(ReceiptManager.class).received(from, id, requests);
}
// TODO parse chat states
// TODO collect Extensions that require transformation (everything that will end up in the
// message tables)
// TODO pass pubsub events to pubsub manager
// TODO pass JMI to JingleManager
}
private boolean isRoot() {
return this.level == Level.ROOT;
}
private boolean isRealtimeProcessor() {
return this.level != Level.ARCHIVE;
}
public enum Level {
ROOT,
CARBON,
ARCHIVE
}
}