rewrote parser code. mam id and possible other stuff still missing. also massivly untested
This commit is contained in:
		
							parent
							
								
									e32f380dae
								
							
						
					
					
						commit
						d261feda74
					
				| 
						 | 
					@ -11,6 +11,7 @@ import eu.siacs.conversations.entities.Contact;
 | 
				
			||||||
import eu.siacs.conversations.services.XmppConnectionService;
 | 
					import eu.siacs.conversations.services.XmppConnectionService;
 | 
				
			||||||
import eu.siacs.conversations.xml.Element;
 | 
					import eu.siacs.conversations.xml.Element;
 | 
				
			||||||
import eu.siacs.conversations.xmpp.jid.Jid;
 | 
					import eu.siacs.conversations.xmpp.jid.Jid;
 | 
				
			||||||
 | 
					import eu.siacs.conversations.xmpp.stanzas.MessagePacket;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
public abstract class AbstractParser {
 | 
					public abstract class AbstractParser {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -20,22 +21,23 @@ public abstract class AbstractParser {
 | 
				
			||||||
		this.mXmppConnectionService = service;
 | 
							this.mXmppConnectionService = service;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						public static Long getTimestamp(Element element, Long defaultValue) {
 | 
				
			||||||
 | 
							Element delay = element.findChild("delay");
 | 
				
			||||||
 | 
							if (delay != null) {
 | 
				
			||||||
 | 
								String stamp = delay.getAttribute("stamp");
 | 
				
			||||||
 | 
								if (stamp != null) {
 | 
				
			||||||
 | 
									try {
 | 
				
			||||||
 | 
										return AbstractParser.parseTimestamp(delay.getAttribute("stamp")).getTime();
 | 
				
			||||||
 | 
									} catch (ParseException e) {
 | 
				
			||||||
 | 
										return defaultValue;
 | 
				
			||||||
 | 
									}
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							return defaultValue;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	protected long getTimestamp(Element packet) {
 | 
						protected long getTimestamp(Element packet) {
 | 
				
			||||||
		long now = System.currentTimeMillis();
 | 
							return getTimestamp(packet,System.currentTimeMillis());
 | 
				
			||||||
		Element delay = packet.findChild("delay");
 | 
					 | 
				
			||||||
		if (delay == null) {
 | 
					 | 
				
			||||||
			return now;
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
		String stamp = delay.getAttribute("stamp");
 | 
					 | 
				
			||||||
		if (stamp == null) {
 | 
					 | 
				
			||||||
			return now;
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
		try {
 | 
					 | 
				
			||||||
			long time = parseTimestamp(stamp).getTime();
 | 
					 | 
				
			||||||
			return now < time ? now : time;
 | 
					 | 
				
			||||||
		} catch (ParseException e) {
 | 
					 | 
				
			||||||
			return now;
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	public static Date parseTimestamp(String timestamp) throws ParseException {
 | 
						public static Date parseTimestamp(String timestamp) throws ParseException {
 | 
				
			||||||
| 
						 | 
					@ -46,14 +48,11 @@ public abstract class AbstractParser {
 | 
				
			||||||
		return dateFormat.parse(timestamp);
 | 
							return dateFormat.parse(timestamp);
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	protected void updateLastseen(final Element packet, final Account account,
 | 
						protected void updateLastseen(final Element packet, final Account account, final boolean presenceOverwrite) {
 | 
				
			||||||
			final boolean presenceOverwrite) {
 | 
							updateLastseen(packet, account, packet.getAttributeAsJid("from"), presenceOverwrite);
 | 
				
			||||||
		final Jid from = packet.getAttributeAsJid("from");
 | 
					 | 
				
			||||||
		updateLastseen(packet, account, from, presenceOverwrite);
 | 
					 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	protected void updateLastseen(final Element packet, final Account account, final Jid from,
 | 
						protected void updateLastseen(final Element packet, final Account account, final Jid from, final boolean presenceOverwrite) {
 | 
				
			||||||
								  final boolean presenceOverwrite) {
 | 
					 | 
				
			||||||
		final String presence = from == null || from.isBareJid() ? "" : from.getResourcepart();
 | 
							final String presence = from == null || from.isBareJid() ? "" : from.getResourcepart();
 | 
				
			||||||
		final Contact contact = account.getRoster().getContact(from);
 | 
							final Contact contact = account.getRoster().getContact(from);
 | 
				
			||||||
		final long timestamp = getTimestamp(packet);
 | 
							final long timestamp = getTimestamp(packet);
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1,8 +1,12 @@
 | 
				
			||||||
package eu.siacs.conversations.parser;
 | 
					package eu.siacs.conversations.parser;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import android.util.Log;
 | 
				
			||||||
 | 
					import android.util.Pair;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import net.java.otr4j.session.Session;
 | 
					import net.java.otr4j.session.Session;
 | 
				
			||||||
import net.java.otr4j.session.SessionStatus;
 | 
					import net.java.otr4j.session.SessionStatus;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import eu.siacs.conversations.Config;
 | 
				
			||||||
import eu.siacs.conversations.entities.Account;
 | 
					import eu.siacs.conversations.entities.Account;
 | 
				
			||||||
import eu.siacs.conversations.entities.Contact;
 | 
					import eu.siacs.conversations.entities.Contact;
 | 
				
			||||||
import eu.siacs.conversations.entities.Conversation;
 | 
					import eu.siacs.conversations.entities.Conversation;
 | 
				
			||||||
| 
						 | 
					@ -25,12 +29,12 @@ public class MessageParser extends AbstractParser implements
 | 
				
			||||||
		super(service);
 | 
							super(service);
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	private boolean extractChatState(Conversation conversation, final Element element) {
 | 
						private boolean extractChatState(Conversation conversation, final MessagePacket packet) {
 | 
				
			||||||
		ChatState state = ChatState.parse(element);
 | 
							ChatState state = ChatState.parse(packet);
 | 
				
			||||||
		if (state != null && conversation != null) {
 | 
							if (state != null && conversation != null) {
 | 
				
			||||||
			final Account account = conversation.getAccount();
 | 
								final Account account = conversation.getAccount();
 | 
				
			||||||
			Jid from = element.getAttributeAsJid("from");
 | 
								Jid from = packet.getFrom();
 | 
				
			||||||
			if (from != null && from.toBareJid().equals(account.getJid().toBareJid())) {
 | 
								if (from.toBareJid().equals(account.getJid().toBareJid())) {
 | 
				
			||||||
				conversation.setOutgoingChatState(state);
 | 
									conversation.setOutgoingChatState(state);
 | 
				
			||||||
				return false;
 | 
									return false;
 | 
				
			||||||
			} else {
 | 
								} else {
 | 
				
			||||||
| 
						 | 
					@ -40,86 +44,27 @@ public class MessageParser extends AbstractParser implements
 | 
				
			||||||
		return false;
 | 
							return false;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	private Message parseChat(MessagePacket packet, Account account) {
 | 
						private Message parseOtrChat(String body, Jid from, String id, Conversation conversation) {
 | 
				
			||||||
		final Jid jid = packet.getFrom();
 | 
					 | 
				
			||||||
		if (jid == null) {
 | 
					 | 
				
			||||||
			return null;
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
		Conversation conversation = mXmppConnectionService.findOrCreateConversation(account, jid.toBareJid(), false);
 | 
					 | 
				
			||||||
		String pgpBody = getPgpBody(packet);
 | 
					 | 
				
			||||||
		Message finishedMessage;
 | 
					 | 
				
			||||||
		if (pgpBody != null) {
 | 
					 | 
				
			||||||
			finishedMessage = new Message(conversation,
 | 
					 | 
				
			||||||
					pgpBody, Message.ENCRYPTION_PGP, Message.STATUS_RECEIVED);
 | 
					 | 
				
			||||||
		} else {
 | 
					 | 
				
			||||||
			finishedMessage = new Message(conversation,
 | 
					 | 
				
			||||||
					packet.getBody(), Message.ENCRYPTION_NONE,
 | 
					 | 
				
			||||||
					Message.STATUS_RECEIVED);
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
		finishedMessage.setRemoteMsgId(packet.getId());
 | 
					 | 
				
			||||||
		finishedMessage.markable = isMarkable(packet);
 | 
					 | 
				
			||||||
		if (conversation.getMode() == Conversation.MODE_MULTI
 | 
					 | 
				
			||||||
				&& !jid.isBareJid()) {
 | 
					 | 
				
			||||||
			final Jid trueCounterpart = conversation.getMucOptions()
 | 
					 | 
				
			||||||
					.getTrueCounterpart(jid.getResourcepart());
 | 
					 | 
				
			||||||
			if (trueCounterpart != null) {
 | 
					 | 
				
			||||||
				updateLastseen(packet, account, trueCounterpart, false);
 | 
					 | 
				
			||||||
			}
 | 
					 | 
				
			||||||
			finishedMessage.setType(Message.TYPE_PRIVATE);
 | 
					 | 
				
			||||||
			finishedMessage.setTrueCounterpart(trueCounterpart);
 | 
					 | 
				
			||||||
			if (conversation.hasDuplicateMessage(finishedMessage)) {
 | 
					 | 
				
			||||||
				return null;
 | 
					 | 
				
			||||||
			}
 | 
					 | 
				
			||||||
		} else {
 | 
					 | 
				
			||||||
			updateLastseen(packet, account, true);
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
		finishedMessage.setCounterpart(jid);
 | 
					 | 
				
			||||||
		finishedMessage.setTime(getTimestamp(packet));
 | 
					 | 
				
			||||||
		extractChatState(conversation,packet);
 | 
					 | 
				
			||||||
		return finishedMessage;
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	private Message parseOtrChat(MessagePacket packet, Account account) {
 | 
					 | 
				
			||||||
		final Jid to = packet.getTo();
 | 
					 | 
				
			||||||
		final Jid from = packet.getFrom();
 | 
					 | 
				
			||||||
		if (to == null || from == null) {
 | 
					 | 
				
			||||||
			return null;
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
		boolean properlyAddressed = !to.isBareJid() || account.countPresences() == 1;
 | 
					 | 
				
			||||||
		Conversation conversation = mXmppConnectionService
 | 
					 | 
				
			||||||
				.findOrCreateConversation(account, from.toBareJid(), false);
 | 
					 | 
				
			||||||
		String presence;
 | 
							String presence;
 | 
				
			||||||
		if (from.isBareJid()) {
 | 
							if (from.isBareJid()) {
 | 
				
			||||||
			presence = "";
 | 
								presence = "";
 | 
				
			||||||
		} else {
 | 
							} else {
 | 
				
			||||||
			presence = from.getResourcepart();
 | 
								presence = from.getResourcepart();
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		extractChatState(conversation, packet);
 | 
					 | 
				
			||||||
		updateLastseen(packet, account, true);
 | 
					 | 
				
			||||||
		String body = packet.getBody();
 | 
					 | 
				
			||||||
		if (body.matches("^\\?OTRv\\d{1,2}\\?.*")) {
 | 
							if (body.matches("^\\?OTRv\\d{1,2}\\?.*")) {
 | 
				
			||||||
			conversation.endOtrIfNeeded();
 | 
								conversation.endOtrIfNeeded();
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		if (!conversation.hasValidOtrSession()) {
 | 
							if (!conversation.hasValidOtrSession()) {
 | 
				
			||||||
			if (properlyAddressed) {
 | 
								conversation.startOtrSession(presence,false);
 | 
				
			||||||
				conversation.startOtrSession(presence,false);
 | 
					 | 
				
			||||||
			} else {
 | 
					 | 
				
			||||||
				return null;
 | 
					 | 
				
			||||||
			}
 | 
					 | 
				
			||||||
		} else {
 | 
							} else {
 | 
				
			||||||
			String foreignPresence = conversation.getOtrSession()
 | 
								String foreignPresence = conversation.getOtrSession().getSessionID().getUserID();
 | 
				
			||||||
					.getSessionID().getUserID();
 | 
					 | 
				
			||||||
			if (!foreignPresence.equals(presence)) {
 | 
								if (!foreignPresence.equals(presence)) {
 | 
				
			||||||
				conversation.endOtrIfNeeded();
 | 
									conversation.endOtrIfNeeded();
 | 
				
			||||||
				if (properlyAddressed) {
 | 
									conversation.startOtrSession(presence, false);
 | 
				
			||||||
					conversation.startOtrSession(presence, false);
 | 
					 | 
				
			||||||
				} else {
 | 
					 | 
				
			||||||
					return null;
 | 
					 | 
				
			||||||
				}
 | 
					 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		try {
 | 
							try {
 | 
				
			||||||
			conversation.setLastReceivedOtrMessageId(packet.getId());
 | 
								conversation.setLastReceivedOtrMessageId(id);
 | 
				
			||||||
			Session otrSession = conversation.getOtrSession();
 | 
								Session otrSession = conversation.getOtrSession();
 | 
				
			||||||
			SessionStatus before = otrSession.getSessionStatus();
 | 
								SessionStatus before = otrSession.getSessionStatus();
 | 
				
			||||||
			body = otrSession.transformReceiving(body);
 | 
								body = otrSession.transformReceiving(body);
 | 
				
			||||||
| 
						 | 
					@ -140,12 +85,7 @@ public class MessageParser extends AbstractParser implements
 | 
				
			||||||
				conversation.setSymmetricKey(CryptoHelper.hexToBytes(key));
 | 
									conversation.setSymmetricKey(CryptoHelper.hexToBytes(key));
 | 
				
			||||||
				return null;
 | 
									return null;
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
			Message finishedMessage = new Message(conversation, body, Message.ENCRYPTION_OTR,
 | 
								Message finishedMessage = new Message(conversation, body, Message.ENCRYPTION_OTR, Message.STATUS_RECEIVED);
 | 
				
			||||||
					Message.STATUS_RECEIVED);
 | 
					 | 
				
			||||||
			finishedMessage.setTime(getTimestamp(packet));
 | 
					 | 
				
			||||||
			finishedMessage.setRemoteMsgId(packet.getId());
 | 
					 | 
				
			||||||
			finishedMessage.markable = isMarkable(packet);
 | 
					 | 
				
			||||||
			finishedMessage.setCounterpart(from);
 | 
					 | 
				
			||||||
			conversation.setLastReceivedOtrMessageId(null);
 | 
								conversation.setLastReceivedOtrMessageId(null);
 | 
				
			||||||
			return finishedMessage;
 | 
								return finishedMessage;
 | 
				
			||||||
		} catch (Exception e) {
 | 
							} catch (Exception e) {
 | 
				
			||||||
| 
						 | 
					@ -154,293 +94,6 @@ public class MessageParser extends AbstractParser implements
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	private Message parseGroupchat(MessagePacket packet, Account account) {
 | 
					 | 
				
			||||||
		int status;
 | 
					 | 
				
			||||||
		final Jid from = packet.getFrom();
 | 
					 | 
				
			||||||
		if (from == null) {
 | 
					 | 
				
			||||||
			return null;
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
		if (mXmppConnectionService.find(account.pendingConferenceLeaves,
 | 
					 | 
				
			||||||
				account, from.toBareJid()) != null) {
 | 
					 | 
				
			||||||
			return null;
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
		Conversation conversation = mXmppConnectionService
 | 
					 | 
				
			||||||
				.findOrCreateConversation(account, from.toBareJid(), true);
 | 
					 | 
				
			||||||
		final Jid trueCounterpart = conversation.getMucOptions().getTrueCounterpart(from.getResourcepart());
 | 
					 | 
				
			||||||
		if (trueCounterpart != null) {
 | 
					 | 
				
			||||||
			updateLastseen(packet, account, trueCounterpart, false);
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
		if (packet.hasChild("subject")) {
 | 
					 | 
				
			||||||
			conversation.setHasMessagesLeftOnServer(true);
 | 
					 | 
				
			||||||
			conversation.getMucOptions().setSubject(packet.findChild("subject").getContent());
 | 
					 | 
				
			||||||
			mXmppConnectionService.updateConversationUi();
 | 
					 | 
				
			||||||
			return null;
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		final Element x = packet.findChild("x", "http://jabber.org/protocol/muc#user");
 | 
					 | 
				
			||||||
		if (from.isBareJid() && (x == null || !x.hasChild("status"))) {
 | 
					 | 
				
			||||||
			return null;
 | 
					 | 
				
			||||||
		} else if (from.isBareJid() && x.hasChild("status")) {
 | 
					 | 
				
			||||||
			for(Element child : x.getChildren()) {
 | 
					 | 
				
			||||||
				if (child.getName().equals("status")) {
 | 
					 | 
				
			||||||
					String code = child.getAttribute("code");
 | 
					 | 
				
			||||||
					if (code.contains(MucOptions.STATUS_CODE_ROOM_CONFIG_CHANGED)) {
 | 
					 | 
				
			||||||
						mXmppConnectionService.fetchConferenceConfiguration(conversation);
 | 
					 | 
				
			||||||
					}
 | 
					 | 
				
			||||||
				}
 | 
					 | 
				
			||||||
			}
 | 
					 | 
				
			||||||
			return null;
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		if (from.getResourcepart().equals(conversation.getMucOptions().getActualNick())) {
 | 
					 | 
				
			||||||
			if (mXmppConnectionService.markMessage(conversation,
 | 
					 | 
				
			||||||
					packet.getId(), Message.STATUS_SEND_RECEIVED)) {
 | 
					 | 
				
			||||||
				return null;
 | 
					 | 
				
			||||||
			} else if (packet.getId() == null) {
 | 
					 | 
				
			||||||
				Message message = conversation.findSentMessageWithBody(packet.getBody());
 | 
					 | 
				
			||||||
				if (message != null) {
 | 
					 | 
				
			||||||
					mXmppConnectionService.markMessage(message,Message.STATUS_SEND_RECEIVED);
 | 
					 | 
				
			||||||
					return null;
 | 
					 | 
				
			||||||
				} else {
 | 
					 | 
				
			||||||
					status = Message.STATUS_SEND;
 | 
					 | 
				
			||||||
				}
 | 
					 | 
				
			||||||
			} else {
 | 
					 | 
				
			||||||
				status = Message.STATUS_SEND;
 | 
					 | 
				
			||||||
			}
 | 
					 | 
				
			||||||
		} else {
 | 
					 | 
				
			||||||
			status = Message.STATUS_RECEIVED;
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
		String pgpBody = getPgpBody(packet);
 | 
					 | 
				
			||||||
		Message finishedMessage;
 | 
					 | 
				
			||||||
		if (pgpBody == null) {
 | 
					 | 
				
			||||||
			finishedMessage = new Message(conversation,
 | 
					 | 
				
			||||||
					packet.getBody(), Message.ENCRYPTION_NONE, status);
 | 
					 | 
				
			||||||
		} else {
 | 
					 | 
				
			||||||
			finishedMessage = new Message(conversation, pgpBody,
 | 
					 | 
				
			||||||
					Message.ENCRYPTION_PGP, status);
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
		finishedMessage.setRemoteMsgId(packet.getId());
 | 
					 | 
				
			||||||
		finishedMessage.markable = isMarkable(packet);
 | 
					 | 
				
			||||||
		finishedMessage.setCounterpart(from);
 | 
					 | 
				
			||||||
		if (status == Message.STATUS_RECEIVED) {
 | 
					 | 
				
			||||||
			finishedMessage.setTrueCounterpart(conversation.getMucOptions()
 | 
					 | 
				
			||||||
					.getTrueCounterpart(from.getResourcepart()));
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
		if (packet.hasChild("delay")
 | 
					 | 
				
			||||||
				&& conversation.hasDuplicateMessage(finishedMessage)) {
 | 
					 | 
				
			||||||
			return null;
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
		finishedMessage.setTime(getTimestamp(packet));
 | 
					 | 
				
			||||||
		return finishedMessage;
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	private Message parseCarbonMessage(final MessagePacket packet, final Account account) {
 | 
					 | 
				
			||||||
		int status;
 | 
					 | 
				
			||||||
		final Jid fullJid;
 | 
					 | 
				
			||||||
		Element forwarded;
 | 
					 | 
				
			||||||
		if (packet.hasChild("received", "urn:xmpp:carbons:2")) {
 | 
					 | 
				
			||||||
			forwarded = packet.findChild("received", "urn:xmpp:carbons:2")
 | 
					 | 
				
			||||||
					.findChild("forwarded", "urn:xmpp:forward:0");
 | 
					 | 
				
			||||||
			status = Message.STATUS_RECEIVED;
 | 
					 | 
				
			||||||
		} else if (packet.hasChild("sent", "urn:xmpp:carbons:2")) {
 | 
					 | 
				
			||||||
			forwarded = packet.findChild("sent", "urn:xmpp:carbons:2")
 | 
					 | 
				
			||||||
					.findChild("forwarded", "urn:xmpp:forward:0");
 | 
					 | 
				
			||||||
			status = Message.STATUS_SEND;
 | 
					 | 
				
			||||||
		} else {
 | 
					 | 
				
			||||||
			return null;
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
		if (forwarded == null) {
 | 
					 | 
				
			||||||
			return null;
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
		Element message = forwarded.findChild("message");
 | 
					 | 
				
			||||||
		if (message == null) {
 | 
					 | 
				
			||||||
			return null;
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
		if (!message.hasChild("body")) {
 | 
					 | 
				
			||||||
			if (status == Message.STATUS_RECEIVED
 | 
					 | 
				
			||||||
					&& message.getAttribute("from") != null) {
 | 
					 | 
				
			||||||
				parseNonMessage(message, account);
 | 
					 | 
				
			||||||
			} else if (status == Message.STATUS_SEND
 | 
					 | 
				
			||||||
					&& message.hasChild("displayed", "urn:xmpp:chat-markers:0")) {
 | 
					 | 
				
			||||||
				final Jid to = message.getAttributeAsJid("to");
 | 
					 | 
				
			||||||
				if (to != null) {
 | 
					 | 
				
			||||||
					final Conversation conversation = mXmppConnectionService.find(
 | 
					 | 
				
			||||||
							mXmppConnectionService.getConversations(), account,
 | 
					 | 
				
			||||||
							to.toBareJid());
 | 
					 | 
				
			||||||
					if (conversation != null) {
 | 
					 | 
				
			||||||
						mXmppConnectionService.markRead(conversation);
 | 
					 | 
				
			||||||
					}
 | 
					 | 
				
			||||||
				}
 | 
					 | 
				
			||||||
			}
 | 
					 | 
				
			||||||
			return null;
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
		if (status == Message.STATUS_RECEIVED) {
 | 
					 | 
				
			||||||
			fullJid = message.getAttributeAsJid("from");
 | 
					 | 
				
			||||||
			if (fullJid == null) {
 | 
					 | 
				
			||||||
				return null;
 | 
					 | 
				
			||||||
			} else {
 | 
					 | 
				
			||||||
				updateLastseen(message, account, true);
 | 
					 | 
				
			||||||
			}
 | 
					 | 
				
			||||||
		} else {
 | 
					 | 
				
			||||||
			fullJid = message.getAttributeAsJid("to");
 | 
					 | 
				
			||||||
			if (fullJid == null) {
 | 
					 | 
				
			||||||
				return null;
 | 
					 | 
				
			||||||
			}
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
		if (message.hasChild("x","http://jabber.org/protocol/muc#user")
 | 
					 | 
				
			||||||
				&& "chat".equals(message.getAttribute("type"))) {
 | 
					 | 
				
			||||||
			return null;
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
		Conversation conversation = mXmppConnectionService
 | 
					 | 
				
			||||||
				.findOrCreateConversation(account, fullJid.toBareJid(), false);
 | 
					 | 
				
			||||||
		String pgpBody = getPgpBody(message);
 | 
					 | 
				
			||||||
		Message finishedMessage;
 | 
					 | 
				
			||||||
		if (pgpBody != null) {
 | 
					 | 
				
			||||||
			finishedMessage = new Message(conversation, pgpBody,
 | 
					 | 
				
			||||||
					Message.ENCRYPTION_PGP, status);
 | 
					 | 
				
			||||||
		} else {
 | 
					 | 
				
			||||||
			String body = message.findChild("body").getContent();
 | 
					 | 
				
			||||||
			finishedMessage = new Message(conversation, body,
 | 
					 | 
				
			||||||
					Message.ENCRYPTION_NONE, status);
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
		extractChatState(conversation,message);
 | 
					 | 
				
			||||||
		finishedMessage.setTime(getTimestamp(message));
 | 
					 | 
				
			||||||
		finishedMessage.setRemoteMsgId(message.getAttribute("id"));
 | 
					 | 
				
			||||||
		finishedMessage.markable = isMarkable(message);
 | 
					 | 
				
			||||||
		finishedMessage.setCounterpart(fullJid);
 | 
					 | 
				
			||||||
		if (conversation.getMode() == Conversation.MODE_MULTI
 | 
					 | 
				
			||||||
				&& !fullJid.isBareJid()) {
 | 
					 | 
				
			||||||
			finishedMessage.setType(Message.TYPE_PRIVATE);
 | 
					 | 
				
			||||||
			finishedMessage.setTrueCounterpart(conversation.getMucOptions()
 | 
					 | 
				
			||||||
					.getTrueCounterpart(fullJid.getResourcepart()));
 | 
					 | 
				
			||||||
			if (conversation.hasDuplicateMessage(finishedMessage)) {
 | 
					 | 
				
			||||||
				return null;
 | 
					 | 
				
			||||||
			}
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
		return finishedMessage;
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	private Message parseMamMessage(MessagePacket packet, final Account account) {
 | 
					 | 
				
			||||||
		final Element result = packet.findChild("result","urn:xmpp:mam:0");
 | 
					 | 
				
			||||||
		if (result == null ) {
 | 
					 | 
				
			||||||
			return null;
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
		final MessageArchiveService.Query query = this.mXmppConnectionService.getMessageArchiveService().findQuery(result.getAttribute("queryid"));
 | 
					 | 
				
			||||||
		if (query!=null) {
 | 
					 | 
				
			||||||
			query.incrementTotalCount();
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
		final Element forwarded = result.findChild("forwarded","urn:xmpp:forward:0");
 | 
					 | 
				
			||||||
		if (forwarded == null) {
 | 
					 | 
				
			||||||
			return null;
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
		final Element message = forwarded.findChild("message");
 | 
					 | 
				
			||||||
		if (message == null) {
 | 
					 | 
				
			||||||
			return null;
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
		final Element body = message.findChild("body");
 | 
					 | 
				
			||||||
		if (body == null || message.hasChild("private","urn:xmpp:carbons:2") || message.hasChild("no-copy","urn:xmpp:hints")) {
 | 
					 | 
				
			||||||
			return null;
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
		int encryption;
 | 
					 | 
				
			||||||
		String content = getPgpBody(message);
 | 
					 | 
				
			||||||
		if (content != null) {
 | 
					 | 
				
			||||||
			encryption = Message.ENCRYPTION_PGP;
 | 
					 | 
				
			||||||
		} else {
 | 
					 | 
				
			||||||
			encryption = Message.ENCRYPTION_NONE;
 | 
					 | 
				
			||||||
			content = body.getContent();
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
		if (content == null) {
 | 
					 | 
				
			||||||
			return null;
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
		final long timestamp = getTimestamp(forwarded);
 | 
					 | 
				
			||||||
		final Jid to = message.getAttributeAsJid("to");
 | 
					 | 
				
			||||||
		final Jid from = message.getAttributeAsJid("from");
 | 
					 | 
				
			||||||
		Jid counterpart;
 | 
					 | 
				
			||||||
		int status;
 | 
					 | 
				
			||||||
		Conversation conversation;
 | 
					 | 
				
			||||||
		if (from!=null && to != null && from.toBareJid().equals(account.getJid().toBareJid())) {
 | 
					 | 
				
			||||||
			status = Message.STATUS_SEND;
 | 
					 | 
				
			||||||
			conversation = this.mXmppConnectionService.findOrCreateConversation(account,to.toBareJid(),false,query);
 | 
					 | 
				
			||||||
			counterpart = to;
 | 
					 | 
				
			||||||
		} else if (from !=null && to != null) {
 | 
					 | 
				
			||||||
			status = Message.STATUS_RECEIVED;
 | 
					 | 
				
			||||||
			conversation = this.mXmppConnectionService.findOrCreateConversation(account,from.toBareJid(),false,query);
 | 
					 | 
				
			||||||
			counterpart = from;
 | 
					 | 
				
			||||||
		} else {
 | 
					 | 
				
			||||||
			return null;
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
		Message finishedMessage = new Message(conversation,content,encryption,status);
 | 
					 | 
				
			||||||
		finishedMessage.setTime(timestamp);
 | 
					 | 
				
			||||||
		finishedMessage.setCounterpart(counterpart);
 | 
					 | 
				
			||||||
		finishedMessage.setRemoteMsgId(message.getAttribute("id"));
 | 
					 | 
				
			||||||
		finishedMessage.setServerMsgId(result.getAttribute("id"));
 | 
					 | 
				
			||||||
		if (conversation.hasDuplicateMessage(finishedMessage)) {
 | 
					 | 
				
			||||||
			return null;
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
		if (query!=null) {
 | 
					 | 
				
			||||||
			query.incrementMessageCount();
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
		return finishedMessage;
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	private void parseError(final MessagePacket packet, final Account account) {
 | 
					 | 
				
			||||||
		final Jid from = packet.getFrom();
 | 
					 | 
				
			||||||
		mXmppConnectionService.markMessage(account, from.toBareJid(),
 | 
					 | 
				
			||||||
				packet.getId(), Message.STATUS_SEND_FAILED);
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	private void parseNonMessage(Element packet, Account account) {
 | 
					 | 
				
			||||||
		final Jid from = packet.getAttributeAsJid("from");
 | 
					 | 
				
			||||||
		if (account.getJid().equals(from)) {
 | 
					 | 
				
			||||||
			return;
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
		if (extractChatState(from == null ? null : mXmppConnectionService.find(account,from), packet)) {
 | 
					 | 
				
			||||||
			mXmppConnectionService.updateConversationUi();
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
		Invite invite = extractInvite(packet);
 | 
					 | 
				
			||||||
		if (invite != null && invite.jid != null) {
 | 
					 | 
				
			||||||
			Conversation conversation = mXmppConnectionService.findOrCreateConversation(account, invite.jid, true);
 | 
					 | 
				
			||||||
			if (!conversation.getMucOptions().online()) {
 | 
					 | 
				
			||||||
				conversation.getMucOptions().setPassword(invite.password);
 | 
					 | 
				
			||||||
				mXmppConnectionService.databaseBackend.updateConversation(conversation);
 | 
					 | 
				
			||||||
				mXmppConnectionService.joinMuc(conversation);
 | 
					 | 
				
			||||||
				mXmppConnectionService.updateConversationUi();
 | 
					 | 
				
			||||||
			}
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
		if (packet.hasChild("event", "http://jabber.org/protocol/pubsub#event")) {
 | 
					 | 
				
			||||||
			Element event = packet.findChild("event",
 | 
					 | 
				
			||||||
					"http://jabber.org/protocol/pubsub#event");
 | 
					 | 
				
			||||||
			parseEvent(event, from, account);
 | 
					 | 
				
			||||||
		} else if (from != null && packet.hasChild("displayed", "urn:xmpp:chat-markers:0")) {
 | 
					 | 
				
			||||||
			String id = packet
 | 
					 | 
				
			||||||
					.findChild("displayed", "urn:xmpp:chat-markers:0")
 | 
					 | 
				
			||||||
					.getAttribute("id");
 | 
					 | 
				
			||||||
			updateLastseen(packet, account, true);
 | 
					 | 
				
			||||||
			final Message displayedMessage = mXmppConnectionService.markMessage(account, from.toBareJid(), id, Message.STATUS_SEND_DISPLAYED);
 | 
					 | 
				
			||||||
			Message message = displayedMessage == null ? null :displayedMessage.prev();
 | 
					 | 
				
			||||||
			while (message != null
 | 
					 | 
				
			||||||
					&& message.getStatus() == Message.STATUS_SEND_RECEIVED
 | 
					 | 
				
			||||||
					&& message.getTimeSent() < displayedMessage.getTimeSent()) {
 | 
					 | 
				
			||||||
				mXmppConnectionService.markMessage(message, Message.STATUS_SEND_DISPLAYED);
 | 
					 | 
				
			||||||
				message = message.prev();
 | 
					 | 
				
			||||||
			}
 | 
					 | 
				
			||||||
		} else if (from != null
 | 
					 | 
				
			||||||
				&& packet.hasChild("received", "urn:xmpp:chat-markers:0")) {
 | 
					 | 
				
			||||||
			String id = packet.findChild("received", "urn:xmpp:chat-markers:0")
 | 
					 | 
				
			||||||
					.getAttribute("id");
 | 
					 | 
				
			||||||
			updateLastseen(packet, account, false);
 | 
					 | 
				
			||||||
			mXmppConnectionService.markMessage(account, from.toBareJid(),
 | 
					 | 
				
			||||||
					id, Message.STATUS_SEND_RECEIVED);
 | 
					 | 
				
			||||||
		} else if (from != null
 | 
					 | 
				
			||||||
				&& packet.hasChild("received", "urn:xmpp:receipts")) {
 | 
					 | 
				
			||||||
			String id = packet.findChild("received", "urn:xmpp:receipts")
 | 
					 | 
				
			||||||
					.getAttribute("id");
 | 
					 | 
				
			||||||
			updateLastseen(packet, account, false);
 | 
					 | 
				
			||||||
			mXmppConnectionService.markMessage(account, from.toBareJid(),
 | 
					 | 
				
			||||||
					id, Message.STATUS_SEND_RECEIVED);
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	private class Invite {
 | 
						private class Invite {
 | 
				
			||||||
		Jid jid;
 | 
							Jid jid;
 | 
				
			||||||
		String password;
 | 
							String password;
 | 
				
			||||||
| 
						 | 
					@ -451,7 +104,7 @@ public class MessageParser extends AbstractParser implements
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	private Invite extractInvite(Element message) {
 | 
						private Invite extractInvite(Element message) {
 | 
				
			||||||
		Element x = message.findChild("x","http://jabber.org/protocol/muc#user");
 | 
							Element x = message.findChild("x", "http://jabber.org/protocol/muc#user");
 | 
				
			||||||
		if (x != null) {
 | 
							if (x != null) {
 | 
				
			||||||
			Element invite = x.findChild("invite");
 | 
								Element invite = x.findChild("invite");
 | 
				
			||||||
			if (invite != null) {
 | 
								if (invite != null) {
 | 
				
			||||||
| 
						 | 
					@ -523,142 +176,208 @@ public class MessageParser extends AbstractParser implements
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	private String getPgpBody(Element message) {
 | 
					 | 
				
			||||||
		Element child = message.findChild("x", "jabber:x:encrypted");
 | 
					 | 
				
			||||||
		if (child == null) {
 | 
					 | 
				
			||||||
			return null;
 | 
					 | 
				
			||||||
		} else {
 | 
					 | 
				
			||||||
			return child.getContent();
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	private boolean isMarkable(Element message) {
 | 
					 | 
				
			||||||
		return message.hasChild("markable", "urn:xmpp:chat-markers:0");
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	@Override
 | 
						@Override
 | 
				
			||||||
	public void onMessagePacketReceived(Account account, MessagePacket packet) {
 | 
						public void onMessagePacketReceived(Account account, MessagePacket original) {
 | 
				
			||||||
		Message message = null;
 | 
							final MessagePacket packet;
 | 
				
			||||||
		this.parseNick(packet, account);
 | 
							Long timestamp = null;
 | 
				
			||||||
		if ((packet.getType() == MessagePacket.TYPE_CHAT || packet.getType() == MessagePacket.TYPE_NORMAL)) {
 | 
							final boolean isForwarded;
 | 
				
			||||||
			if ((packet.getBody() != null)
 | 
							boolean carbon = false; //live carbons or mam-sub
 | 
				
			||||||
					&& (packet.getBody().startsWith("?OTR"))) {
 | 
							if (original.fromServer(account)) {
 | 
				
			||||||
				message = this.parseOtrChat(packet, account);
 | 
								Pair<MessagePacket, Long> f;
 | 
				
			||||||
				if (message != null) {
 | 
								f = original.getForwardedMessagePacket("received", "urn:xmpp:carbons:2");
 | 
				
			||||||
					message.markUnread();
 | 
								f = f == null ? original.getForwardedMessagePacket("sent", "urn:xmpp:carbons:2") : f;
 | 
				
			||||||
				}
 | 
								f = f == null ? original.getForwardedMessagePacket("result", "urn:xmpp:mam:0") : f;
 | 
				
			||||||
			} else if (packet.hasChild("body") && extractInvite(packet) == null) {
 | 
								packet = f != null ? f.first : original;
 | 
				
			||||||
				message = this.parseChat(packet, account);
 | 
								timestamp = f != null ? f.second : null;
 | 
				
			||||||
				if (message != null) {
 | 
								isForwarded = f != null;
 | 
				
			||||||
					message.markUnread();
 | 
								carbon = original.hasChild("received", "urn:xmpp:carbons:2") || original.hasChild("received", "urn:xmpp:carbons:2");
 | 
				
			||||||
				}
 | 
					
 | 
				
			||||||
			} else if (packet.hasChild("received", "urn:xmpp:carbons:2")
 | 
								Element fin = packet.findChild("fin", "urn:xmpp:mam:0");
 | 
				
			||||||
					|| (packet.hasChild("sent", "urn:xmpp:carbons:2"))) {
 | 
								if (fin != null) {
 | 
				
			||||||
				message = this.parseCarbonMessage(packet, account);
 | 
					 | 
				
			||||||
				if (message != null) {
 | 
					 | 
				
			||||||
					if (message.getStatus() == Message.STATUS_SEND) {
 | 
					 | 
				
			||||||
						account.activateGracePeriod();
 | 
					 | 
				
			||||||
						mXmppConnectionService.markRead(message.getConversation());
 | 
					 | 
				
			||||||
					} else {
 | 
					 | 
				
			||||||
						message.markUnread();
 | 
					 | 
				
			||||||
					}
 | 
					 | 
				
			||||||
				}
 | 
					 | 
				
			||||||
			} else if (packet.hasChild("result","urn:xmpp:mam:0")) {
 | 
					 | 
				
			||||||
				message = parseMamMessage(packet, account);
 | 
					 | 
				
			||||||
				if (message != null) {
 | 
					 | 
				
			||||||
					Conversation conversation = message.getConversation();
 | 
					 | 
				
			||||||
					conversation.add(message);
 | 
					 | 
				
			||||||
					mXmppConnectionService.databaseBackend.createMessage(message);
 | 
					 | 
				
			||||||
				}
 | 
					 | 
				
			||||||
				return;
 | 
					 | 
				
			||||||
			} else if (packet.hasChild("fin","urn:xmpp:mam:0")) {
 | 
					 | 
				
			||||||
				Element fin = packet.findChild("fin","urn:xmpp:mam:0");
 | 
					 | 
				
			||||||
				mXmppConnectionService.getMessageArchiveService().processFin(fin);
 | 
									mXmppConnectionService.getMessageArchiveService().processFin(fin);
 | 
				
			||||||
			} else {
 | 
									return;
 | 
				
			||||||
				parseNonMessage(packet, account);
 | 
					 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
		} else if (packet.getType() == MessagePacket.TYPE_GROUPCHAT) {
 | 
					
 | 
				
			||||||
			message = this.parseGroupchat(packet, account);
 | 
							} else {
 | 
				
			||||||
			if (message != null) {
 | 
								packet = original;
 | 
				
			||||||
				if (message.getStatus() == Message.STATUS_RECEIVED) {
 | 
								isForwarded = false;
 | 
				
			||||||
					message.markUnread();
 | 
							}
 | 
				
			||||||
 | 
							if (timestamp == null) {
 | 
				
			||||||
 | 
								timestamp = AbstractParser.getTimestamp(packet, System.currentTimeMillis());
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							final String body = packet.getBody();
 | 
				
			||||||
 | 
							final String encrypted = packet.findChildContent("x", "jabber:x:encrypted");
 | 
				
			||||||
 | 
							int status;
 | 
				
			||||||
 | 
							final Jid to = packet.getTo();
 | 
				
			||||||
 | 
							final Jid from = packet.getFrom();
 | 
				
			||||||
 | 
							final Jid counterpart;
 | 
				
			||||||
 | 
							final String id = packet.getId();
 | 
				
			||||||
 | 
							boolean isTypeGroupChat = packet.getType() == MessagePacket.TYPE_GROUPCHAT;
 | 
				
			||||||
 | 
							boolean properlyAddressed = !to.isBareJid() || account.countPresences() == 1;
 | 
				
			||||||
 | 
							if (packet.fromAccount(account)) {
 | 
				
			||||||
 | 
								status = Message.STATUS_SEND;
 | 
				
			||||||
 | 
								counterpart = to;
 | 
				
			||||||
 | 
							} else {
 | 
				
			||||||
 | 
								status = Message.STATUS_RECEIVED;
 | 
				
			||||||
 | 
								counterpart = from;
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							if (from == null || to == null) {
 | 
				
			||||||
 | 
								Log.d(Config.LOGTAG,"no to or from in: "+packet.toString());
 | 
				
			||||||
 | 
								return;
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							Invite invite = extractInvite(packet);
 | 
				
			||||||
 | 
							if (invite != null && invite.jid != null) {
 | 
				
			||||||
 | 
								Conversation conversation = mXmppConnectionService.findOrCreateConversation(account, invite.jid, true);
 | 
				
			||||||
 | 
								if (!conversation.getMucOptions().online()) {
 | 
				
			||||||
 | 
									conversation.getMucOptions().setPassword(invite.password);
 | 
				
			||||||
 | 
									mXmppConnectionService.databaseBackend.updateConversation(conversation);
 | 
				
			||||||
 | 
									mXmppConnectionService.joinMuc(conversation);
 | 
				
			||||||
 | 
									mXmppConnectionService.updateConversationUi();
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
								return;
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							if (extractChatState(mXmppConnectionService.find(account,from), packet)) {
 | 
				
			||||||
 | 
								mXmppConnectionService.updateConversationUi();
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							if (body != null || encrypted != null) {
 | 
				
			||||||
 | 
								Conversation conversation = mXmppConnectionService.findOrCreateConversation(account, counterpart.toBareJid(), isTypeGroupChat);
 | 
				
			||||||
 | 
								if (isTypeGroupChat) {
 | 
				
			||||||
 | 
									if (counterpart.getResourcepart().equals(conversation.getMucOptions().getActualNick())) {
 | 
				
			||||||
 | 
										status = Message.STATUS_SEND;
 | 
				
			||||||
 | 
										if (mXmppConnectionService.markMessage(conversation, id, Message.STATUS_SEND_RECEIVED)) {
 | 
				
			||||||
 | 
											return;
 | 
				
			||||||
 | 
										} else if (id == null) {
 | 
				
			||||||
 | 
											Message message = conversation.findSentMessageWithBody(packet.getBody());
 | 
				
			||||||
 | 
											if (message != null) {
 | 
				
			||||||
 | 
												mXmppConnectionService.markMessage(message, Message.STATUS_SEND_RECEIVED);
 | 
				
			||||||
 | 
												return;
 | 
				
			||||||
 | 
											}
 | 
				
			||||||
 | 
										}
 | 
				
			||||||
				} else {
 | 
									} else {
 | 
				
			||||||
					mXmppConnectionService.markRead(message.getConversation());
 | 
										status = Message.STATUS_RECEIVED;
 | 
				
			||||||
					account.activateGracePeriod();
 | 
					 | 
				
			||||||
				}
 | 
									}
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
		} else if (packet.getType() == MessagePacket.TYPE_ERROR) {
 | 
								Message message;
 | 
				
			||||||
			this.parseError(packet, account);
 | 
								if (body != null && body.startsWith("?OTR")) {
 | 
				
			||||||
			return;
 | 
									if (!isForwarded && !isTypeGroupChat && properlyAddressed) {
 | 
				
			||||||
		} else if (packet.getType() == MessagePacket.TYPE_HEADLINE) {
 | 
										message = parseOtrChat(body, from, id, conversation);
 | 
				
			||||||
			this.parseHeadline(packet, account);
 | 
										if (message == null) {
 | 
				
			||||||
			return;
 | 
											return;
 | 
				
			||||||
		}
 | 
										}
 | 
				
			||||||
		if ((message == null) || (message.getBody() == null)) {
 | 
									} else {
 | 
				
			||||||
			return;
 | 
										message = new Message(conversation, body, Message.ENCRYPTION_NONE, status);
 | 
				
			||||||
		}
 | 
									}
 | 
				
			||||||
		if ((mXmppConnectionService.confirmMessages())
 | 
								} else if (encrypted != null) {
 | 
				
			||||||
				&& ((packet.getId() != null))) {
 | 
									message = new Message(conversation, encrypted, Message.ENCRYPTION_PGP, status);
 | 
				
			||||||
			if (packet.hasChild("markable", "urn:xmpp:chat-markers:0")) {
 | 
								} else {
 | 
				
			||||||
				MessagePacket receipt = mXmppConnectionService
 | 
									message = new Message(conversation, body, Message.ENCRYPTION_NONE, status);
 | 
				
			||||||
						.getMessageGenerator().received(account, packet,
 | 
					 | 
				
			||||||
								"urn:xmpp:chat-markers:0");
 | 
					 | 
				
			||||||
				mXmppConnectionService.sendMessagePacket(account, receipt);
 | 
					 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
			if (packet.hasChild("request", "urn:xmpp:receipts")) {
 | 
								message.setCounterpart(counterpart);
 | 
				
			||||||
				MessagePacket receipt = mXmppConnectionService
 | 
								message.setRemoteMsgId(id);
 | 
				
			||||||
						.getMessageGenerator().received(account, packet,
 | 
								message.setTime(timestamp);
 | 
				
			||||||
								"urn:xmpp:receipts");
 | 
								message.markable = packet.hasChild("markable", "urn:xmpp:chat-markers:0");
 | 
				
			||||||
				mXmppConnectionService.sendMessagePacket(account, receipt);
 | 
								if (conversation.getMode() == Conversation.MODE_MULTI) {
 | 
				
			||||||
 | 
									message.setTrueCounterpart(conversation.getMucOptions().getTrueCounterpart(counterpart.getResourcepart()));
 | 
				
			||||||
 | 
									if (!isTypeGroupChat) {
 | 
				
			||||||
 | 
										message.setType(Message.TYPE_PRIVATE);
 | 
				
			||||||
 | 
									}
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
		}
 | 
								updateLastseen(packet,account,true);
 | 
				
			||||||
		Conversation conversation = message.getConversation();
 | 
								conversation.add(message);
 | 
				
			||||||
		conversation.add(message);
 | 
								if (carbon || status == Message.STATUS_RECEIVED) {
 | 
				
			||||||
		if (account.getXmppConnection() != null && account.getXmppConnection().getFeatures().advancedStreamFeaturesLoaded()) {
 | 
									mXmppConnectionService.markRead(conversation);
 | 
				
			||||||
			if (conversation.setLastMessageTransmitted(System.currentTimeMillis())) {
 | 
									account.activateGracePeriod();
 | 
				
			||||||
				mXmppConnectionService.updateConversation(conversation);
 | 
								} else if (!isForwarded) {
 | 
				
			||||||
 | 
									message.markUnread();
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
		if (message.getStatus() == Message.STATUS_RECEIVED
 | 
					 | 
				
			||||||
				&& conversation.getOtrSession() != null
 | 
					 | 
				
			||||||
				&& !conversation.getOtrSession().getSessionID().getUserID()
 | 
					 | 
				
			||||||
				.equals(message.getCounterpart().getResourcepart())) {
 | 
					 | 
				
			||||||
			conversation.endOtrIfNeeded();
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
		if (packet.getType() != MessagePacket.TYPE_ERROR) {
 | 
								if (mXmppConnectionService.confirmMessages() && id != null && !packet.fromAccount(account)) {
 | 
				
			||||||
 | 
									if (packet.hasChild("markable", "urn:xmpp:chat-markers:0")) {
 | 
				
			||||||
 | 
										MessagePacket receipt = mXmppConnectionService
 | 
				
			||||||
 | 
												.getMessageGenerator().received(account, packet, "urn:xmpp:chat-markers:0");
 | 
				
			||||||
 | 
										mXmppConnectionService.sendMessagePacket(account, receipt);
 | 
				
			||||||
 | 
									}
 | 
				
			||||||
 | 
									if (packet.hasChild("request", "urn:xmpp:receipts")) {
 | 
				
			||||||
 | 
										MessagePacket receipt = mXmppConnectionService
 | 
				
			||||||
 | 
												.getMessageGenerator().received(account, packet, "urn:xmpp:receipts");
 | 
				
			||||||
 | 
										mXmppConnectionService.sendMessagePacket(account, receipt);
 | 
				
			||||||
 | 
									}
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
								if (account.getXmppConnection() != null && account.getXmppConnection().getFeatures().advancedStreamFeaturesLoaded()) {
 | 
				
			||||||
 | 
									if (conversation.setLastMessageTransmitted(System.currentTimeMillis())) {
 | 
				
			||||||
 | 
										mXmppConnectionService.updateConversation(conversation);
 | 
				
			||||||
 | 
									}
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								if (message.getStatus() == Message.STATUS_RECEIVED
 | 
				
			||||||
 | 
										&& conversation.getOtrSession() != null
 | 
				
			||||||
 | 
										&& !conversation.getOtrSession().getSessionID().getUserID()
 | 
				
			||||||
 | 
										.equals(message.getCounterpart().getResourcepart())) {
 | 
				
			||||||
 | 
									conversation.endOtrIfNeeded();
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			if (message.getEncryption() == Message.ENCRYPTION_NONE
 | 
								if (message.getEncryption() == Message.ENCRYPTION_NONE
 | 
				
			||||||
					|| mXmppConnectionService.saveEncryptedMessages()) {
 | 
										|| mXmppConnectionService.saveEncryptedMessages()) {
 | 
				
			||||||
				mXmppConnectionService.databaseBackend.createMessage(message);
 | 
									mXmppConnectionService.databaseBackend.createMessage(message);
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
		}
 | 
								final HttpConnectionManager manager = this.mXmppConnectionService.getHttpConnectionManager();
 | 
				
			||||||
		final HttpConnectionManager manager = this.mXmppConnectionService.getHttpConnectionManager();
 | 
								if (message.trusted() && message.bodyContainsDownloadable() && manager.getAutoAcceptFileSize() > 0) {
 | 
				
			||||||
		if (message.trusted() && message.bodyContainsDownloadable() && manager.getAutoAcceptFileSize() > 0) {
 | 
									manager.createNewConnection(message);
 | 
				
			||||||
			manager.createNewConnection(message);
 | 
								} else if (!message.isRead()) {
 | 
				
			||||||
		} else if (!message.isRead()) {
 | 
									mXmppConnectionService.getNotificationService().push(message);
 | 
				
			||||||
			mXmppConnectionService.getNotificationService().push(message);
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
		mXmppConnectionService.updateConversationUi();
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	private void parseHeadline(MessagePacket packet, Account account) {
 | 
					 | 
				
			||||||
		if (packet.hasChild("event", "http://jabber.org/protocol/pubsub#event")) {
 | 
					 | 
				
			||||||
			Element event = packet.findChild("event",
 | 
					 | 
				
			||||||
					"http://jabber.org/protocol/pubsub#event");
 | 
					 | 
				
			||||||
			parseEvent(event, packet.getFrom(), account);
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	private void parseNick(MessagePacket packet, Account account) {
 | 
					 | 
				
			||||||
		Element nick = packet.findChild("nick",
 | 
					 | 
				
			||||||
				"http://jabber.org/protocol/nick");
 | 
					 | 
				
			||||||
		if (nick != null) {
 | 
					 | 
				
			||||||
			if (packet.getFrom() != null) {
 | 
					 | 
				
			||||||
				Contact contact = account.getRoster().getContact(
 | 
					 | 
				
			||||||
						packet.getFrom());
 | 
					 | 
				
			||||||
				contact.setPresenceName(nick.getContent());
 | 
					 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
 | 
								mXmppConnectionService.updateConversationUi();
 | 
				
			||||||
 | 
							} else {
 | 
				
			||||||
 | 
								if (packet.hasChild("subject") && isTypeGroupChat) {
 | 
				
			||||||
 | 
									Conversation conversation = mXmppConnectionService.find(account, from.toBareJid());
 | 
				
			||||||
 | 
									if (conversation != null && conversation.getMode() == Conversation.MODE_MULTI) {
 | 
				
			||||||
 | 
										conversation.setHasMessagesLeftOnServer(true);
 | 
				
			||||||
 | 
										conversation.getMucOptions().setSubject(packet.findChildContent("subject"));
 | 
				
			||||||
 | 
										mXmppConnectionService.updateConversationUi();
 | 
				
			||||||
 | 
										return;
 | 
				
			||||||
 | 
									}
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							Element received = packet.findChild("received", "urn:xmpp:chat-markers:0");
 | 
				
			||||||
 | 
							if (received == null) {
 | 
				
			||||||
 | 
								received = packet.findChild("received", "urn:xmpp:receipts");
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							if (received != null && !packet.fromAccount(account)) {
 | 
				
			||||||
 | 
								mXmppConnectionService.markMessage(account, from.toBareJid(), received.getAttribute("id"), Message.STATUS_SEND_RECEIVED);
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							Element displayed = packet.findChild("displayed", "urn:xmpp:chat-markers:0");
 | 
				
			||||||
 | 
							if (displayed != null) {
 | 
				
			||||||
 | 
								if (packet.fromAccount(account)) {
 | 
				
			||||||
 | 
									Conversation conversation = mXmppConnectionService.find(account,counterpart.toBareJid());
 | 
				
			||||||
 | 
									mXmppConnectionService.markRead(conversation);
 | 
				
			||||||
 | 
								} else {
 | 
				
			||||||
 | 
									updateLastseen(packet, account, true);
 | 
				
			||||||
 | 
									final Message displayedMessage = mXmppConnectionService.markMessage(account, from.toBareJid(), displayed.getAttribute("id"), Message.STATUS_SEND_DISPLAYED);
 | 
				
			||||||
 | 
									Message message = displayedMessage == null ? null : displayedMessage.prev();
 | 
				
			||||||
 | 
									while (message != null
 | 
				
			||||||
 | 
											&& message.getStatus() == Message.STATUS_SEND_RECEIVED
 | 
				
			||||||
 | 
											&& message.getTimeSent() < displayedMessage.getTimeSent()) {
 | 
				
			||||||
 | 
										mXmppConnectionService.markMessage(message, Message.STATUS_SEND_DISPLAYED);
 | 
				
			||||||
 | 
										message = message.prev();
 | 
				
			||||||
 | 
									}
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							Element event = packet.findChild("event", "http://jabber.org/protocol/pubsub#event");
 | 
				
			||||||
 | 
							if (event != null) {
 | 
				
			||||||
 | 
								parseEvent(event, from, account);
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							String nick = packet.findChildContent("nick", "http://jabber.org/protocol/nick");
 | 
				
			||||||
 | 
							if (nick != null) {
 | 
				
			||||||
 | 
								Contact contact = account.getRoster().getContact(from);
 | 
				
			||||||
 | 
								contact.setPresenceName(nick);
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					@ -51,4 +51,8 @@ public class AbstractStanza extends Element {
 | 
				
			||||||
			|| getTo().equals(account.getJid().toBareJid())
 | 
								|| getTo().equals(account.getJid().toBareJid())
 | 
				
			||||||
			|| getTo().equals(account.getJid());
 | 
								|| getTo().equals(account.getJid());
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						public boolean fromAccount(final Account account) {
 | 
				
			||||||
 | 
							return getFrom() != null && getFrom().toBareJid().equals(account.getJid().toBareJid());
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1,5 +1,10 @@
 | 
				
			||||||
package eu.siacs.conversations.xmpp.stanzas;
 | 
					package eu.siacs.conversations.xmpp.stanzas;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import android.util.Pair;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import java.text.ParseException;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import eu.siacs.conversations.parser.AbstractParser;
 | 
				
			||||||
import eu.siacs.conversations.xml.Element;
 | 
					import eu.siacs.conversations.xml.Element;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
public class MessagePacket extends AbstractStanza {
 | 
					public class MessagePacket extends AbstractStanza {
 | 
				
			||||||
| 
						 | 
					@ -14,12 +19,7 @@ public class MessagePacket extends AbstractStanza {
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	public String getBody() {
 | 
						public String getBody() {
 | 
				
			||||||
		Element body = this.findChild("body");
 | 
							return findChildContent("body");
 | 
				
			||||||
		if (body != null) {
 | 
					 | 
				
			||||||
			return body.getContent();
 | 
					 | 
				
			||||||
		} else {
 | 
					 | 
				
			||||||
			return null;
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	public void setBody(String text) {
 | 
						public void setBody(String text) {
 | 
				
			||||||
| 
						 | 
					@ -67,19 +67,23 @@ public class MessagePacket extends AbstractStanza {
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	public MessagePacket getForwardedMessagePacket(String name, String namespace) {
 | 
						public Pair<MessagePacket,Long> getForwardedMessagePacket(String name, String namespace) {
 | 
				
			||||||
		Element wrapper = findChild(name, namespace);
 | 
							Element wrapper = findChild(name, namespace);
 | 
				
			||||||
		if (wrapper == null) {
 | 
							if (wrapper == null) {
 | 
				
			||||||
			return null;
 | 
								return null;
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		Element forwarded = wrapper.findChild("forwarded","urn:xmpp:forward:0");
 | 
							Element forwarded = wrapper.findChild("forwarded", "urn:xmpp:forward:0");
 | 
				
			||||||
		if (forwarded == null) {
 | 
							if (forwarded == null) {
 | 
				
			||||||
			return null;
 | 
								return null;
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		return MessagePacket.create(forwarded.findChild("message"));
 | 
							MessagePacket packet = create(forwarded.findChild("message"));
 | 
				
			||||||
 | 
							if (packet == null) {
 | 
				
			||||||
 | 
								return null;
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							Long timestamp = AbstractParser.getTimestamp(forwarded,null);
 | 
				
			||||||
 | 
							return new Pair(packet,timestamp);
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					 | 
				
			||||||
	public static MessagePacket create(Element element) {
 | 
						public static MessagePacket create(Element element) {
 | 
				
			||||||
		if (element == null) {
 | 
							if (element == null) {
 | 
				
			||||||
			return null;
 | 
								return null;
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
		Reference in New Issue