private static Date getDelay(Message m) { // first: new XEP-0203 specification ExtensionElement delay = DelayInformation.from(m); // fallback: obsolete XEP-0091 specification if (delay == null) { delay = m.getExtension("x", "jabber:x:delay"); } if (delay instanceof DelayInformation) { Date date = ((DelayInformation) delay).getStamp(); if (date.after(new Date())) LOGGER.warning("delay time is in future: "+date); return date; } return null; }
/** * Get Delayed Delivery information. This method first looks for a PacketExtension with the * XEP-203 namespace and falls back to the XEP-91 namespace. * * @param packet * @return the Delayed Delivery information or <code>null</code> */ public static DelayInformation getDelayInformation(Stanza packet) { DelayInformation delayInformation = getXep203DelayInformation(packet); if (delayInformation != null) { return delayInformation; } return getLegacyDelayInformation(packet); }
/** * Get the Delayed Delivery timestamp or <code>null</code> * * @param packet * @return the Delayed Delivery timestamp or <code>null</code> */ public static Date getDelayTimestamp(Stanza packet) { DelayInformation delayInformation = getDelayInformation(packet); if (delayInformation == null) { return null; } return delayInformation.getStamp(); }
@Override public final DelayInformation parse(XmlPullParser parser, int initialDepth) throws XmlPullParserException, IOException, SmackException { String stampString = (parser.getAttributeValue("", "stamp")); String from = parser.getAttributeValue("", "from"); String reason = null; if (!parser.isEmptyElementTag()) { int event = parser.next(); switch (event) { case XmlPullParser.TEXT: reason = parser.getText(); parser.next(); break; case XmlPullParser.END_TAG: reason = ""; break; default: throw new IllegalStateException("Unexpected event: " + event); } } else { parser.next(); } Date stamp; try { stamp = parseDate(stampString); } catch (ParseException e) { throw new SmackException(e); } return new DelayInformation(stamp, from, reason); }
@Override public Forwarded parse(XmlPullParser parser, int initialDepth) throws XmlPullParserException, IOException, SmackException { DelayInformation di = null; Stanza packet = null; outerloop: while (true) { int eventType = parser.next(); switch (eventType) { case XmlPullParser.START_TAG: String name = parser.getName(); String namespace = parser.getNamespace(); switch (name) { case DelayInformation.ELEMENT: if (DelayInformation.NAMESPACE.equals(namespace)) { di = DelayInformationProvider.INSTANCE.parse(parser, parser.getDepth()); } else { LOGGER.warning("Namespace '" + namespace + "' does not match expected namespace '" + DelayInformation.NAMESPACE + "'"); } break; case Message.ELEMENT: packet = PacketParserUtils.parseMessage(parser); break; default: LOGGER.warning("Unsupported forwarded packet type: " + name); } break; case XmlPullParser.END_TAG: if (parser.getDepth() == initialDepth) { break outerloop; } break; } } if (packet == null) throw new SmackException("forwarded extension must contain a packet"); return new Forwarded(di, packet); }
public static Date getStanzaDelay(Stanza packet) { ExtensionElement _delay = packet.getExtension("delay", "urn:xmpp:delay"); if (_delay == null) _delay = packet.getExtension("x", "jabber:x:delay"); Date stamp = null; if (_delay != null) { if (_delay instanceof DelayInformation) { stamp = ((DelayInformation) _delay).getStamp(); } } return stamp; }
public static Intent createIntent(Context ctx, Presence p, RosterEntry entry) { Intent i = new Intent(ACTION_PRESENCE); Presence.Type type = p.getType(); i.putExtra(EXTRA_TYPE, type != null ? type.name() : Presence.Type.available.name()); i.putExtra(EXTRA_PACKET_ID, p.getStanzaId()); i.putExtra(EXTRA_FROM, StringUtils.maybeToString(p.getFrom().toString())); i.putExtra(EXTRA_TO, StringUtils.maybeToString(p.getTo())); i.putExtra(EXTRA_STATUS, p.getStatus()); Presence.Mode mode = p.getMode(); i.putExtra(EXTRA_SHOW, mode != null ? mode.name() : Presence.Mode.available.name()); i.putExtra(EXTRA_PRIORITY, p.getPriority()); String jid = p.getFrom().asBareJid().toString(); long timestamp; DelayInformation delay = p.getExtension(DelayInformation.ELEMENT, DelayInformation.NAMESPACE); if (delay != null) { timestamp = delay.getStamp().getTime(); } else { // try last seen from database timestamp = UsersProvider.getLastSeen(ctx, jid); if (timestamp < 0) timestamp = System.currentTimeMillis(); } i.putExtra(EXTRA_STAMP, timestamp); // public key fingerprint String fingerprint = PublicKeyPresence.getFingerprint(p); if (fingerprint == null) { // try untrusted fingerprint from database fingerprint = Keyring.getFingerprint(ctx, jid, MyUsers.Keys.TRUST_UNKNOWN); } i.putExtra(EXTRA_FINGERPRINT, fingerprint); // subscription information if (entry != null) { i.putExtra(EXTRA_ROSTER_NAME, entry.getName()); RosterPacket.ItemType subscriptionType = entry.getType(); i.putExtra(EXTRA_SUBSCRIBED_FROM, subscriptionType == RosterPacket.ItemType.both || subscriptionType == RosterPacket.ItemType.from); i.putExtra(EXTRA_SUBSCRIBED_TO, subscriptionType == RosterPacket.ItemType.both || subscriptionType == RosterPacket.ItemType.to); } return i; }
@SuppressWarnings("WeakerAccess") int updateUsersDatabase(Presence p) { String jid = p.getFrom().asBareJid().toString(); ContentValues values = new ContentValues(4); values.put(Users.REGISTERED, 1); // status String status = p.getStatus(); if (status != null) values.put(Users.STATUS, status); else values.putNull(Users.STATUS); // delay long timestamp; DelayInformation delay = p.getExtension(DelayInformation.ELEMENT, DelayInformation.NAMESPACE); if (delay != null) { // delay from presence (rare) timestamp = delay.getStamp().getTime(); } else { // logged in/out now timestamp = System.currentTimeMillis(); } if (timestamp > 0) values.put(Users.LAST_SEEN, timestamp); // public key extension (for fingerprint) PublicKeyPresence pkey = p.getExtension(PublicKeyPresence.ELEMENT_NAME, PublicKeyPresence.NAMESPACE); if (pkey != null) { String fingerprint = pkey.getFingerprint(); if (fingerprint != null) { // insert new key with empty key data Keyring.setKey(getContext(), jid, fingerprint, new Date()); } } return getContext().getContentResolver().update(Users.CONTENT_URI, values, Users.JID + "=?", new String[] { jid }); }
private void handlePresence(Presence p) { Intent i = new Intent(ACTION_PRESENCE); Presence.Type type = p.getType(); i.putExtra(EXTRA_TYPE, type != null ? type.name() : Presence.Type.available.name()); i.putExtra(EXTRA_PACKET_ID, p.getPacketID()); String from = p.getFrom(); String network = StringUtils.parseServer(from); // our network - convert to userId if (network.equalsIgnoreCase(getServer().getNetwork())) { StringBuilder b = new StringBuilder(); b.append(StringUtils.parseName(from)); b.append(StringUtils.parseResource(from)); i.putExtra(EXTRA_FROM_USERID, b.toString()); } i.putExtra(EXTRA_FROM, from); i.putExtra(EXTRA_TO, p.getTo()); i.putExtra(EXTRA_STATUS, p.getStatus()); Presence.Mode mode = p.getMode(); i.putExtra(EXTRA_SHOW, mode != null ? mode.name() : Presence.Mode.available.name()); i.putExtra(EXTRA_PRIORITY, p.getPriority()); // getExtension doesn't work here Iterator<PacketExtension> iter = p.getExtensions().iterator(); while (iter.hasNext()) { PacketExtension _ext = iter.next(); if (_ext instanceof DelayInformation) { DelayInformation delay = (DelayInformation) _ext; i.putExtra(EXTRA_STAMP, delay.getStamp().getTime()); break; } } // non-standard stanza group extension PacketExtension ext = p.getExtension(StanzaGroupExtension.ELEMENT_NAME, StanzaGroupExtension.NAMESPACE); if (ext != null && ext instanceof StanzaGroupExtension) { StanzaGroupExtension g = (StanzaGroupExtension) ext; i.putExtra(EXTRA_GROUP_ID, g.getId()); i.putExtra(EXTRA_GROUP_COUNT, g.getCount()); } Log.v(MessageCenterService.TAG, "broadcasting presence: " + i); sendBroadcast(i); }
/** * Get Delayed Delivery information as defined in XEP-203 * <p> * Prefer {@link #getDelayInformation(Stanza)} over this method for backwards compatibility. * </p> * @param packet * @return the Delayed Delivery information or <code>null</code> */ public static DelayInformation getXep203DelayInformation(Stanza packet) { return DelayInformation.from(packet); }
/** * Get Delayed Delivery information as defined in XEP-91 * <p> * Prefer {@link #getDelayInformation(Stanza)} over this method for backwards compatibility. * </p> * @param packet * @return the Delayed Delivery information or <code>null</code> */ public static DelayInformation getLegacyDelayInformation(Stanza packet) { return packet.getExtension(LEGACY_DELAYED_DELIVERY_ELEMENT, LEGACY_DELAYED_DELIVERY_NAMESPACE); }
/** * Creates a new Forwarded stanza(/packet) extension. * * @param delay an optional {@link DelayInformation} timestamp of the packet. * @param fwdPacket the stanza(/packet) that is forwarded (required). */ public Forwarded(DelayInformation delay, Stanza fwdPacket) { this.delay = delay; this.forwardedPacket = fwdPacket; }
/** * get the timestamp of the forwarded packet. * * @return the {@link DelayInformation} representing the time when the original stanza(/packet) was sent. May be null. */ public DelayInformation getDelayInformation() { return delay; }