diff options
Diffstat (limited to 'src/main/java/de/thedevstack/conversationsplus/xmpp')
13 files changed, 233 insertions, 24 deletions
diff --git a/src/main/java/de/thedevstack/conversationsplus/xmpp/PacketReceived.java b/src/main/java/de/thedevstack/conversationsplus/xmpp/PacketReceived.java index 6274aaa2..de5e2b20 100644 --- a/src/main/java/de/thedevstack/conversationsplus/xmpp/PacketReceived.java +++ b/src/main/java/de/thedevstack/conversationsplus/xmpp/PacketReceived.java @@ -1,5 +1,5 @@ package de.thedevstack.conversationsplus.xmpp; -public abstract interface PacketReceived { +public interface PacketReceived { } diff --git a/src/main/java/de/thedevstack/conversationsplus/xmpp/XmppConnection.java b/src/main/java/de/thedevstack/conversationsplus/xmpp/XmppConnection.java index 2b366dbb..f6e6edb8 100644 --- a/src/main/java/de/thedevstack/conversationsplus/xmpp/XmppConnection.java +++ b/src/main/java/de/thedevstack/conversationsplus/xmpp/XmppConnection.java @@ -62,9 +62,11 @@ import de.thedevstack.conversationsplus.crypto.sasl.ScramSha1; import de.thedevstack.conversationsplus.entities.Account; import de.thedevstack.conversationsplus.entities.Message; import de.thedevstack.conversationsplus.entities.ServiceDiscoveryResult; +import de.thedevstack.conversationsplus.enums.MessageStatus; import de.thedevstack.conversationsplus.generator.IqGenerator; import de.thedevstack.conversationsplus.services.XmppConnectionService; import de.thedevstack.conversationsplus.utils.DNSHelper; +import de.thedevstack.conversationsplus.utils.MessageUtil; import de.thedevstack.conversationsplus.utils.SSLSocketHelper; import de.thedevstack.conversationsplus.utils.Xmlns; import de.thedevstack.conversationsplus.xml.Element; @@ -492,10 +494,10 @@ public class XmppConnection implements Runnable { for(AbstractAcknowledgeableStanza packet : failedStanzas) { if (packet instanceof MessagePacket) { MessagePacket message = (MessagePacket) packet; - mXmppConnectionService.markMessage(account, + Message msg = mXmppConnectionService.getMessage(account, message.getTo().toBareJid(), - message.getId(), - Message.STATUS_UNSEND); + message.getId()); + MessageUtil.setAndSaveMessageStatus(msg, MessageStatus.TRANSMITTING); } sendPacket(packet); } diff --git a/src/main/java/de/thedevstack/conversationsplus/xmpp/chatmarkers/ChatMarkers.java b/src/main/java/de/thedevstack/conversationsplus/xmpp/chatmarkers/ChatMarkers.java new file mode 100644 index 00000000..a1822b7d --- /dev/null +++ b/src/main/java/de/thedevstack/conversationsplus/xmpp/chatmarkers/ChatMarkers.java @@ -0,0 +1,28 @@ +package de.thedevstack.conversationsplus.xmpp.chatmarkers; + +import de.thedevstack.conversationsplus.xml.Element; +import de.thedevstack.conversationsplus.xml.XmlElementContainer; + +/** + * Representation of the ChatMarkers hint. + * <pre> + * <markable xmlns="urn:xmpp:chat-markers:0"/> + * </pre> + */ +public enum ChatMarkers implements XmlElementContainer { + MARKABLE("markable"), + RECEIVED("received"), + DISPLAYED("displayed"), + ACKNOWLEDGED("acknowledged"); + + private final Element xmlElement; + + ChatMarkers(String elementName) { + this.xmlElement = new Element(elementName, ChatMarkersXep.NAMESPACE); + } + + @Override + public Element getXmlElement() { + return xmlElement; + } +} diff --git a/src/main/java/de/thedevstack/conversationsplus/xmpp/chatmarkers/ChatMarkersHandler.java b/src/main/java/de/thedevstack/conversationsplus/xmpp/chatmarkers/ChatMarkersHandler.java new file mode 100644 index 00000000..a8277a04 --- /dev/null +++ b/src/main/java/de/thedevstack/conversationsplus/xmpp/chatmarkers/ChatMarkersHandler.java @@ -0,0 +1,11 @@ +package de.thedevstack.conversationsplus.xmpp.chatmarkers; + +import de.thedevstack.conversationsplus.entities.Account; +import de.thedevstack.conversationsplus.xmpp.jid.Jid; + +/** + */ +public interface ChatMarkersHandler { + void messageReceived(Account account, Jid from, String messageId); + void messageDisplayed(Account account, Jid from, String messageId); +} diff --git a/src/main/java/de/thedevstack/conversationsplus/xmpp/chatmarkers/ChatMarkersPacketHandler.java b/src/main/java/de/thedevstack/conversationsplus/xmpp/chatmarkers/ChatMarkersPacketHandler.java new file mode 100644 index 00000000..89fd945a --- /dev/null +++ b/src/main/java/de/thedevstack/conversationsplus/xmpp/chatmarkers/ChatMarkersPacketHandler.java @@ -0,0 +1,24 @@ +package de.thedevstack.conversationsplus.xmpp.chatmarkers; + +import de.thedevstack.conversationsplus.entities.Account; +import de.thedevstack.conversationsplus.entities.Message; +import de.thedevstack.conversationsplus.xml.Element; +import de.thedevstack.conversationsplus.xmpp.stanzas.MessagePacket; + +/** + */ +public class ChatMarkersPacketHandler { + private ChatMarkersHandler handler; + + public void handleMessagePacket(Account account, MessagePacket packet, Message message) { + message.markable = packet.hasChild("markable", ChatMarkersXep.NAMESPACE); + Element received = packet.findChild("received", ChatMarkersXep.NAMESPACE); + if (null != received && null != handler) { + handler.messageReceived(account, packet.getFrom().toBareJid(), received.getAttribute("id")); + } + Element displayed = packet.findChild("displayed", ChatMarkersXep.NAMESPACE); + if (null != displayed && null != handler) { + handler.messageDisplayed(account, packet.getFrom().toBareJid(), displayed.getAttribute("id")); + } + } +} diff --git a/src/main/java/de/thedevstack/conversationsplus/xmpp/chatmarkers/ChatMarkersXep.java b/src/main/java/de/thedevstack/conversationsplus/xmpp/chatmarkers/ChatMarkersXep.java new file mode 100644 index 00000000..58f3f66e --- /dev/null +++ b/src/main/java/de/thedevstack/conversationsplus/xmpp/chatmarkers/ChatMarkersXep.java @@ -0,0 +1,49 @@ +package de.thedevstack.conversationsplus.xmpp.chatmarkers; + +import de.thedevstack.conversationsplus.xmpp.AbstractXep; +import de.thedevstack.conversationsplus.xmpp.IqPacketHandler; + +/** + */ +public class ChatMarkersXep extends AbstractXep { + public static final String NAMESPACE = "urn:xmpp:chat-markers:0"; + + public ChatMarkersXep(boolean enabled) { + super(enabled); + } + + @Override + public String xepNumber() { + return "0333"; + } + + @Override + public String shortName() { + return ""; + } + + @Override + public String name() { + return "Chat Markers"; + } + + @Override + public String namespace() { + return NAMESPACE; + } + + @Override + public String featureNamespace() { + return namespace(); + } + + @Override + public String elementName() { + return null; + } + + @Override + public IqPacketHandler handler() { + return null; + } +} diff --git a/src/main/java/de/thedevstack/conversationsplus/xmpp/disco/FeatureRegistry.java b/src/main/java/de/thedevstack/conversationsplus/xmpp/disco/FeatureRegistry.java index 1c266545..cb53e993 100644 --- a/src/main/java/de/thedevstack/conversationsplus/xmpp/disco/FeatureRegistry.java +++ b/src/main/java/de/thedevstack/conversationsplus/xmpp/disco/FeatureRegistry.java @@ -34,7 +34,6 @@ public final class FeatureRegistry { ChatState.NAMESPACE, AxolotlService.PEP_DEVICE_LIST+"+notify"}; private static final String[] LEGACY_MESSAGE_CONFIRMATION_FEATURES = { - "urn:xmpp:chat-markers:0", "urn:xmpp:receipts" }; private final List<String> features = new ArrayList<>(); diff --git a/src/main/java/de/thedevstack/conversationsplus/xmpp/httpuploadim/HttpUploadHint.java b/src/main/java/de/thedevstack/conversationsplus/xmpp/httpuploadim/HttpUploadHint.java index 13fb5ad1..1330b18d 100644 --- a/src/main/java/de/thedevstack/conversationsplus/xmpp/httpuploadim/HttpUploadHint.java +++ b/src/main/java/de/thedevstack/conversationsplus/xmpp/httpuploadim/HttpUploadHint.java @@ -1,6 +1,7 @@ package de.thedevstack.conversationsplus.xmpp.httpuploadim; import de.thedevstack.conversationsplus.xml.Element; +import de.thedevstack.conversationsplus.xml.XmlElementContainer; /** * Representation of the HttpUploadHint. @@ -8,18 +9,23 @@ import de.thedevstack.conversationsplus.xml.Element; * <httpupload xmlns="urn:xmpp:hints"/> * </pre> */ -public class HttpUploadHint extends Element { +public enum HttpUploadHint implements XmlElementContainer { + HTTP_UPLOAD_HINT("httpupload"); + + private Element xmlElement; + + HttpUploadHint(String elementName) { + this.xmlElement = new Element(elementName, NAMESPACE); + } + + @Override + public Element getXmlElement() { + return xmlElement; + } + /** * The namespace of message processing hints as defined in XEP-0334. * @see <a href="http://xmpp.org/extensions/xep-0334.html">http://xmpp.org/extensions/xep-0334.html</a> */ public static final String NAMESPACE = "urn:xmpp:hints"; - /** - * The element name of the hint for an http upload. - */ - public static final String ELEMENT_NAME = "httpupload"; - - public HttpUploadHint() { - super(ELEMENT_NAME, NAMESPACE); - } } diff --git a/src/main/java/de/thedevstack/conversationsplus/xmpp/jingle/JingleConnection.java b/src/main/java/de/thedevstack/conversationsplus/xmpp/jingle/JingleConnection.java index 49a10684..29e83c34 100644 --- a/src/main/java/de/thedevstack/conversationsplus/xmpp/jingle/JingleConnection.java +++ b/src/main/java/de/thedevstack/conversationsplus/xmpp/jingle/JingleConnection.java @@ -17,6 +17,8 @@ import java.util.concurrent.ConcurrentHashMap; import de.thedevstack.android.logcat.Logging; import de.thedevstack.conversationsplus.ConversationsPlusPreferences; +import de.thedevstack.conversationsplus.enums.MessageDirection; +import de.thedevstack.conversationsplus.enums.MessageStatus; import de.thedevstack.conversationsplus.utils.MessageUtil; import de.thedevstack.conversationsplus.utils.StreamUtil; import de.thedevstack.conversationsplus.Config; @@ -105,7 +107,7 @@ public class JingleConnection implements Transferable { sendSuccess(); MessageUtil.updateFileParams(message); mXmppConnectionService.databaseBackend.createMessage(message); - MessageUtil.markMessage(message,Message.STATUS_RECEIVED); + MessageUtil.setAndSaveMessageStatus(message, MessageStatus.TRANSMITTED); if (acceptedAutomatically) { message.markUnread(); JingleConnection.this.mXmppConnectionService.getNotificationService().push(message); @@ -297,7 +299,8 @@ public class JingleConnection implements Transferable { .findOrCreateConversation(account, packet.getFrom().toBareJid(), false); this.message = new Message(conversation, "", Message.ENCRYPTION_NONE); - this.message.setStatus(Message.STATUS_RECEIVED); + MessageUtil.setMessageStatus(this.message, MessageStatus.TRANSMITTING); + this.message.setDirection(MessageDirection.IN); this.mStatus = Transferable.STATUS_OFFER; this.message.setTransferable(this); final Jid from = packet.getFrom(); @@ -458,7 +461,7 @@ public class JingleConnection implements Transferable { if (packet.getType() == IqPacket.TYPE.RESULT) { Logging.d(Config.LOGTAG,account.getJid().toBareJid()+": other party received offer"); mJingleStatus = JINGLE_STATUS_INITIATED; - MessageUtil.markMessage(message, Message.STATUS_OFFERED); + MessageUtil.setAndSaveMessageStatus(message, MessageStatus.TRANSMITTING); } else { fail(); } @@ -551,7 +554,7 @@ public class JingleConnection implements Transferable { mergeCandidates(JingleCandidate.parse(content.socks5transport() .getChildren())); this.mJingleStatus = JINGLE_STATUS_ACCEPTED; - MessageUtil.markMessage(message, Message.STATUS_UNSEND); + MessageUtil.setAndSaveMessageStatus(message, MessageStatus.TRANSMITTING); this.connectNextCandidate(); return true; } @@ -711,7 +714,7 @@ public class JingleConnection implements Transferable { this.sendJinglePacket(packet); this.disconnectSocks5Connections(); this.mJingleStatus = JINGLE_STATUS_FINISHED; - this.message.setStatus(Message.STATUS_RECEIVED); + MessageUtil.setMessageStatus(message, MessageStatus.TRANSMITTED); this.message.setTransferable(null); this.mXmppConnectionService.updateMessage(message); this.mJingleConnectionManager.finishConnection(this); @@ -783,7 +786,7 @@ public class JingleConnection implements Transferable { private void receiveSuccess() { this.mJingleStatus = JINGLE_STATUS_FINISHED; - MessageUtil.markMessage(this.message,Message.STATUS_SEND_RECEIVED); + MessageUtil.setAndSaveMessageStatus(this.message, MessageStatus.RECEIVED); this.disconnectSocks5Connections(); if (this.transport != null && this.transport instanceof JingleInbandTransport) { this.transport.disconnect(); @@ -806,7 +809,7 @@ public class JingleConnection implements Transferable { } this.mXmppConnectionService.updateConversationUi(); } else { - MessageUtil.markMessage(this.message, Message.STATUS_SEND_FAILED); + MessageUtil.setAndSaveMessageStatus(this.message, MessageStatus.CANCELED); this.message.setTransferable(null); } } @@ -827,7 +830,7 @@ public class JingleConnection implements Transferable { } this.mXmppConnectionService.updateConversationUi(); } else { - MessageUtil.markMessage(this.message, Message.STATUS_SEND_FAILED); + MessageUtil.setAndSaveMessageStatus(this.message, MessageStatus.FAILED); this.message.setTransferable(null); } } diff --git a/src/main/java/de/thedevstack/conversationsplus/xmpp/jingle/JingleConnectionManager.java b/src/main/java/de/thedevstack/conversationsplus/xmpp/jingle/JingleConnectionManager.java index 30ed9024..46fa02b0 100644 --- a/src/main/java/de/thedevstack/conversationsplus/xmpp/jingle/JingleConnectionManager.java +++ b/src/main/java/de/thedevstack/conversationsplus/xmpp/jingle/JingleConnectionManager.java @@ -13,6 +13,7 @@ import de.thedevstack.conversationsplus.Config; import de.thedevstack.conversationsplus.entities.Account; import de.thedevstack.conversationsplus.entities.Message; import de.thedevstack.conversationsplus.entities.Transferable; +import de.thedevstack.conversationsplus.enums.MessageStatus; import de.thedevstack.conversationsplus.services.AbstractConnectionManager; import de.thedevstack.conversationsplus.services.XmppConnectionService; import de.thedevstack.conversationsplus.utils.MessageUtil; @@ -62,7 +63,7 @@ public class JingleConnectionManager extends AbstractConnectionManager { old.cancel(); } JingleConnection connection = new JingleConnection(this); - MessageUtil.markMessage(message,Message.STATUS_WAITING); + MessageUtil.setAndSaveMessageStatus(message, MessageStatus.WAITING); connection.init(message); this.connections.add(connection); return connection; diff --git a/src/main/java/de/thedevstack/conversationsplus/xmpp/muc/MucPacketParser.java b/src/main/java/de/thedevstack/conversationsplus/xmpp/muc/MucPacketParser.java new file mode 100644 index 00000000..d7ec6b38 --- /dev/null +++ b/src/main/java/de/thedevstack/conversationsplus/xmpp/muc/MucPacketParser.java @@ -0,0 +1,62 @@ +package de.thedevstack.conversationsplus.xmpp.muc; + +import de.thedevstack.conversationsplus.entities.Account; +import de.thedevstack.conversationsplus.entities.Conversation; +import de.thedevstack.conversationsplus.persistance.DatabaseBackend; +import de.thedevstack.conversationsplus.utils.UiUpdateHelper; +import de.thedevstack.conversationsplus.utils.XmppConnectionServiceAccessor; +import de.thedevstack.conversationsplus.xml.Element; +import de.thedevstack.conversationsplus.xmpp.jid.Jid; + +/** + */ +public class MucPacketParser { + private static class Invite { + Jid jid; + String password; + Invite(Jid jid, String password) { + this.jid = jid; + this.password = password; + } + + public boolean execute(Account account) { + if (jid != null) { + Conversation conversation = XmppConnectionServiceAccessor.xmppConnectionService.findOrCreateConversation(account, jid, true); + if (!conversation.getMucOptions().online()) { + conversation.getMucOptions().setPassword(password); + DatabaseBackend.getInstance().updateConversation(conversation); + XmppConnectionServiceAccessor.xmppConnectionService.joinMuc(conversation); + UiUpdateHelper.updateConversationUi(); + } + return true; + } + return false; + } + } + + private static Invite extractInvite(Element message) { + Element x = message.findChild("x", "http://jabber.org/protocol/muc#user"); + if (x != null) { + Element invite = x.findChild("invite"); + if (invite != null) { + Element pw = x.findChild("password"); + return new Invite(message.getAttributeAsJid("from"), pw != null ? pw.getContent(): null); + } + } else { + x = message.findChild("x","jabber:x:conference"); + if (x != null) { + return new Invite(x.getAttributeAsJid("jid"),x.getAttribute("password")); + } + } + return null; + } + + public static boolean extractAndExecuteInvite(Account account, Element packet) { + Invite invite = extractInvite(packet); + if (invite != null && invite.execute(account)) { + return true; + } + + return false; + } +} diff --git a/src/main/java/de/thedevstack/conversationsplus/xmpp/receipts/MessageDeliveryReceipts.java b/src/main/java/de/thedevstack/conversationsplus/xmpp/receipts/MessageDeliveryReceipts.java new file mode 100644 index 00000000..1bc86e37 --- /dev/null +++ b/src/main/java/de/thedevstack/conversationsplus/xmpp/receipts/MessageDeliveryReceipts.java @@ -0,0 +1,24 @@ +package de.thedevstack.conversationsplus.xmpp.receipts; + +import de.thedevstack.conversationsplus.xml.Element; +import de.thedevstack.conversationsplus.xml.XmlElementContainer; + +/** + */ +public enum MessageDeliveryReceipts implements XmlElementContainer { + REQUEST("request"), + RECEIVED("received"); + + public static final String NAMESPACE = "urn:xmpp:receipts"; + + private final Element xmlElement; + + MessageDeliveryReceipts(String elementName) { + this.xmlElement = new Element(elementName, NAMESPACE); + } + + @Override + public Element getXmlElement() { + return xmlElement; + } +} diff --git a/src/main/java/de/thedevstack/conversationsplus/xmpp/stanzas/MessagePacket.java b/src/main/java/de/thedevstack/conversationsplus/xmpp/stanzas/MessagePacket.java index e14cdacd..5e9d5a9d 100644 --- a/src/main/java/de/thedevstack/conversationsplus/xmpp/stanzas/MessagePacket.java +++ b/src/main/java/de/thedevstack/conversationsplus/xmpp/stanzas/MessagePacket.java @@ -84,7 +84,7 @@ public class MessagePacket extends AbstractAcknowledgeableStanza { return null; } Long timestamp = AbstractParser.getTimestamp(forwarded,null); - return new Pair(packet,timestamp); + return new Pair<>(packet,timestamp); } public static MessagePacket create(Element element) { |