ignore 'subscribe' presence for blocked contacts

This commit is contained in:
Daniel Gultsch 2024-02-16 16:59:21 +01:00
parent 5692cccf70
commit d175843cbd
No known key found for this signature in database
GPG key ID: F43D18AD2A0982C2

View file

@ -2,11 +2,6 @@ package eu.siacs.conversations.parser;
import android.util.Log; import android.util.Log;
import org.openintents.openpgp.util.OpenPgpUtils;
import java.util.ArrayList;
import java.util.List;
import eu.siacs.conversations.Config; import eu.siacs.conversations.Config;
import eu.siacs.conversations.crypto.PgpEngine; import eu.siacs.conversations.crypto.PgpEngine;
import eu.siacs.conversations.crypto.axolotl.AxolotlService; import eu.siacs.conversations.crypto.axolotl.AxolotlService;
@ -28,123 +23,159 @@ import eu.siacs.conversations.xmpp.OnPresencePacketReceived;
import eu.siacs.conversations.xmpp.pep.Avatar; import eu.siacs.conversations.xmpp.pep.Avatar;
import eu.siacs.conversations.xmpp.stanzas.PresencePacket; import eu.siacs.conversations.xmpp.stanzas.PresencePacket;
public class PresenceParser extends AbstractParser implements import org.openintents.openpgp.util.OpenPgpUtils;
OnPresencePacketReceived {
public PresenceParser(XmppConnectionService service) { import java.util.ArrayList;
super(service); import java.util.List;
}
public void parseConferencePresence(PresencePacket packet, Account account) { public class PresenceParser extends AbstractParser implements OnPresencePacketReceived {
final Conversation conversation = packet.getFrom() == null ? null : mXmppConnectionService.find(account, packet.getFrom().asBareJid());
if (conversation != null) {
final MucOptions mucOptions = conversation.getMucOptions();
boolean before = mucOptions.online();
int count = mucOptions.getUserCount();
final List<MucOptions.User> tileUserBefore = mucOptions.getUsers(5);
processConferencePresence(packet, conversation);
final List<MucOptions.User> tileUserAfter = mucOptions.getUsers(5);
if (!tileUserAfter.equals(tileUserBefore)) {
mXmppConnectionService.getAvatarService().clear(mucOptions);
}
if (before != mucOptions.online() || (mucOptions.online() && count != mucOptions.getUserCount())) {
mXmppConnectionService.updateConversationUi();
} else if (mucOptions.online()) {
mXmppConnectionService.updateMucRosterUi();
}
}
}
private void processConferencePresence(PresencePacket packet, Conversation conversation) { public PresenceParser(XmppConnectionService service) {
final Account account = conversation.getAccount(); super(service);
final MucOptions mucOptions = conversation.getMucOptions(); }
final Jid jid = conversation.getAccount().getJid();
final Jid from = packet.getFrom();
if (!from.isBareJid()) {
final String type = packet.getAttribute("type");
final Element x = packet.findChild("x", Namespace.MUC_USER);
Avatar avatar = Avatar.parsePresence(packet.findChild("x", "vcard-temp:x:update"));
final List<String> codes = getStatusCodes(x);
if (type == null) {
if (x != null) {
Element item = x.findChild("item");
if (item != null && !from.isBareJid()) {
mucOptions.setError(MucOptions.Error.NONE);
MucOptions.User user = parseItem(conversation, item, from);
if (codes.contains(MucOptions.STATUS_CODE_SELF_PRESENCE) || (codes.contains(MucOptions.STATUS_CODE_ROOM_CREATED) && jid.equals(InvalidJid.getNullForInvalid(item.getAttributeAsJid("jid"))))) {
if (mucOptions.setOnline()) {
mXmppConnectionService.getAvatarService().clear(mucOptions);
}
if (mucOptions.setSelf(user)) {
Log.d(Config.LOGTAG,"role or affiliation changed");
mXmppConnectionService.databaseBackend.updateConversation(conversation);
}
mXmppConnectionService.persistSelfNick(user); public void parseConferencePresence(PresencePacket packet, Account account) {
invokeRenameListener(mucOptions, true); final Conversation conversation =
} packet.getFrom() == null
boolean isNew = mucOptions.updateUser(user); ? null
final AxolotlService axolotlService = conversation.getAccount().getAxolotlService(); : mXmppConnectionService.find(account, packet.getFrom().asBareJid());
Contact contact = user.getContact(); if (conversation != null) {
if (isNew final MucOptions mucOptions = conversation.getMucOptions();
&& user.getRealJid() != null boolean before = mucOptions.online();
&& mucOptions.isPrivateAndNonAnonymous() int count = mucOptions.getUserCount();
&& (contact == null || !contact.mutualPresenceSubscription()) final List<MucOptions.User> tileUserBefore = mucOptions.getUsers(5);
&& axolotlService.hasEmptyDeviceList(user.getRealJid())) { processConferencePresence(packet, conversation);
axolotlService.fetchDeviceIds(user.getRealJid()); final List<MucOptions.User> tileUserAfter = mucOptions.getUsers(5);
} if (!tileUserAfter.equals(tileUserBefore)) {
if (codes.contains(MucOptions.STATUS_CODE_ROOM_CREATED) && mucOptions.autoPushConfiguration()) { mXmppConnectionService.getAvatarService().clear(mucOptions);
Log.d(Config.LOGTAG,account.getJid().asBareJid() }
+": room '" if (before != mucOptions.online()
+mucOptions.getConversation().getJid().asBareJid() || (mucOptions.online() && count != mucOptions.getUserCount())) {
+"' created. pushing default configuration"); mXmppConnectionService.updateConversationUi();
mXmppConnectionService.pushConferenceConfiguration(mucOptions.getConversation(), } else if (mucOptions.online()) {
IqGenerator.defaultChannelConfiguration(), mXmppConnectionService.updateMucRosterUi();
null); }
} }
if (mXmppConnectionService.getPgpEngine() != null) { }
Element signed = packet.findChild("x", "jabber:x:signed");
if (signed != null) { private void processConferencePresence(PresencePacket packet, Conversation conversation) {
Element status = packet.findChild("status"); final Account account = conversation.getAccount();
String msg = status == null ? "" : status.getContent(); final MucOptions mucOptions = conversation.getMucOptions();
long keyId = mXmppConnectionService.getPgpEngine().fetchKeyId(mucOptions.getAccount(), msg, signed.getContent()); final Jid jid = conversation.getAccount().getJid();
if (keyId != 0) { final Jid from = packet.getFrom();
user.setPgpKeyId(keyId); if (!from.isBareJid()) {
} final String type = packet.getAttribute("type");
} final Element x = packet.findChild("x", Namespace.MUC_USER);
} Avatar avatar = Avatar.parsePresence(packet.findChild("x", "vcard-temp:x:update"));
if (avatar != null) { final List<String> codes = getStatusCodes(x);
avatar.owner = from; if (type == null) {
if (mXmppConnectionService.getFileBackend().isAvatarCached(avatar)) { if (x != null) {
if (user.setAvatar(avatar)) { Element item = x.findChild("item");
mXmppConnectionService.getAvatarService().clear(user); if (item != null && !from.isBareJid()) {
} mucOptions.setError(MucOptions.Error.NONE);
if (user.getRealJid() != null) { MucOptions.User user = parseItem(conversation, item, from);
final Contact c = conversation.getAccount().getRoster().getContact(user.getRealJid()); if (codes.contains(MucOptions.STATUS_CODE_SELF_PRESENCE)
c.setAvatar(avatar); || (codes.contains(MucOptions.STATUS_CODE_ROOM_CREATED)
mXmppConnectionService.syncRoster(conversation.getAccount()); && jid.equals(
mXmppConnectionService.getAvatarService().clear(c); InvalidJid.getNullForInvalid(
mXmppConnectionService.updateRosterUi(); item.getAttributeAsJid("jid"))))) {
} if (mucOptions.setOnline()) {
} else if (mXmppConnectionService.isDataSaverDisabled()) { mXmppConnectionService.getAvatarService().clear(mucOptions);
mXmppConnectionService.fetchAvatar(mucOptions.getAccount(), avatar); }
} if (mucOptions.setSelf(user)) {
} Log.d(Config.LOGTAG, "role or affiliation changed");
} mXmppConnectionService.databaseBackend.updateConversation(
} conversation);
} else if (type.equals("unavailable")) { }
final boolean fullJidMatches = from.equals(mucOptions.getSelf().getFullJid());
if (x.hasChild("destroy") && fullJidMatches) { mXmppConnectionService.persistSelfNick(user);
Element destroy = x.findChild("destroy"); invokeRenameListener(mucOptions, true);
final Jid alternate = destroy == null ? null : InvalidJid.getNullForInvalid(destroy.getAttributeAsJid("jid")); }
mucOptions.setError(MucOptions.Error.DESTROYED); boolean isNew = mucOptions.updateUser(user);
if (alternate != null) { final AxolotlService axolotlService =
Log.d(Config.LOGTAG, account.getJid().asBareJid() + ": muc destroyed. alternate location " + alternate); conversation.getAccount().getAxolotlService();
} Contact contact = user.getContact();
} else if (codes.contains(MucOptions.STATUS_CODE_SHUTDOWN) && fullJidMatches) { if (isNew
mucOptions.setError(MucOptions.Error.SHUTDOWN); && user.getRealJid() != null
} else if (codes.contains(MucOptions.STATUS_CODE_SELF_PRESENCE)) { && mucOptions.isPrivateAndNonAnonymous()
if (codes.contains(MucOptions.STATUS_CODE_TECHNICAL_REASONS)) { && (contact == null || !contact.mutualPresenceSubscription())
&& axolotlService.hasEmptyDeviceList(user.getRealJid())) {
axolotlService.fetchDeviceIds(user.getRealJid());
}
if (codes.contains(MucOptions.STATUS_CODE_ROOM_CREATED)
&& mucOptions.autoPushConfiguration()) {
Log.d(
Config.LOGTAG,
account.getJid().asBareJid()
+ ": room '"
+ mucOptions.getConversation().getJid().asBareJid()
+ "' created. pushing default configuration");
mXmppConnectionService.pushConferenceConfiguration(
mucOptions.getConversation(),
IqGenerator.defaultChannelConfiguration(),
null);
}
if (mXmppConnectionService.getPgpEngine() != null) {
Element signed = packet.findChild("x", "jabber:x:signed");
if (signed != null) {
Element status = packet.findChild("status");
String msg = status == null ? "" : status.getContent();
long keyId =
mXmppConnectionService
.getPgpEngine()
.fetchKeyId(
mucOptions.getAccount(),
msg,
signed.getContent());
if (keyId != 0) {
user.setPgpKeyId(keyId);
}
}
}
if (avatar != null) {
avatar.owner = from;
if (mXmppConnectionService.getFileBackend().isAvatarCached(avatar)) {
if (user.setAvatar(avatar)) {
mXmppConnectionService.getAvatarService().clear(user);
}
if (user.getRealJid() != null) {
final Contact c =
conversation
.getAccount()
.getRoster()
.getContact(user.getRealJid());
c.setAvatar(avatar);
mXmppConnectionService.syncRoster(conversation.getAccount());
mXmppConnectionService.getAvatarService().clear(c);
mXmppConnectionService.updateRosterUi();
}
} else if (mXmppConnectionService.isDataSaverDisabled()) {
mXmppConnectionService.fetchAvatar(mucOptions.getAccount(), avatar);
}
}
}
}
} else if (type.equals("unavailable")) {
final boolean fullJidMatches = from.equals(mucOptions.getSelf().getFullJid());
if (x.hasChild("destroy") && fullJidMatches) {
Element destroy = x.findChild("destroy");
final Jid alternate =
destroy == null
? null
: InvalidJid.getNullForInvalid(
destroy.getAttributeAsJid("jid"));
mucOptions.setError(MucOptions.Error.DESTROYED);
if (alternate != null) {
Log.d(
Config.LOGTAG,
account.getJid().asBareJid()
+ ": muc destroyed. alternate location "
+ alternate);
}
} else if (codes.contains(MucOptions.STATUS_CODE_SHUTDOWN) && fullJidMatches) {
mucOptions.setError(MucOptions.Error.SHUTDOWN);
} else if (codes.contains(MucOptions.STATUS_CODE_SELF_PRESENCE)) {
if (codes.contains(MucOptions.STATUS_CODE_TECHNICAL_REASONS)) {
final boolean wasOnline = mucOptions.online(); final boolean wasOnline = mucOptions.online();
mucOptions.setError(MucOptions.Error.TECHNICAL_PROBLEMS); mucOptions.setError(MucOptions.Error.TECHNICAL_PROBLEMS);
Log.d( Log.d(
@ -157,238 +188,259 @@ public class PresenceParser extends AbstractParser implements
if (wasOnline) { if (wasOnline) {
mXmppConnectionService.mucSelfPingAndRejoin(conversation); mXmppConnectionService.mucSelfPingAndRejoin(conversation);
} }
} else if (codes.contains(MucOptions.STATUS_CODE_KICKED)) { } else if (codes.contains(MucOptions.STATUS_CODE_KICKED)) {
mucOptions.setError(MucOptions.Error.KICKED); mucOptions.setError(MucOptions.Error.KICKED);
} else if (codes.contains(MucOptions.STATUS_CODE_BANNED)) { } else if (codes.contains(MucOptions.STATUS_CODE_BANNED)) {
mucOptions.setError(MucOptions.Error.BANNED); mucOptions.setError(MucOptions.Error.BANNED);
} else if (codes.contains(MucOptions.STATUS_CODE_LOST_MEMBERSHIP)) { } else if (codes.contains(MucOptions.STATUS_CODE_LOST_MEMBERSHIP)) {
mucOptions.setError(MucOptions.Error.MEMBERS_ONLY); mucOptions.setError(MucOptions.Error.MEMBERS_ONLY);
} else if (codes.contains(MucOptions.STATUS_CODE_AFFILIATION_CHANGE)) { } else if (codes.contains(MucOptions.STATUS_CODE_AFFILIATION_CHANGE)) {
mucOptions.setError(MucOptions.Error.MEMBERS_ONLY); mucOptions.setError(MucOptions.Error.MEMBERS_ONLY);
} else if (codes.contains(MucOptions.STATUS_CODE_SHUTDOWN)) { } else if (codes.contains(MucOptions.STATUS_CODE_SHUTDOWN)) {
mucOptions.setError(MucOptions.Error.SHUTDOWN); mucOptions.setError(MucOptions.Error.SHUTDOWN);
} else if (!codes.contains(MucOptions.STATUS_CODE_CHANGED_NICK)) { } else if (!codes.contains(MucOptions.STATUS_CODE_CHANGED_NICK)) {
mucOptions.setError(MucOptions.Error.UNKNOWN); mucOptions.setError(MucOptions.Error.UNKNOWN);
Log.d(Config.LOGTAG, "unknown error in conference: " + packet); Log.d(Config.LOGTAG, "unknown error in conference: " + packet);
} }
} else if (!from.isBareJid()){ } else if (!from.isBareJid()) {
Element item = x.findChild("item"); Element item = x.findChild("item");
if (item != null) { if (item != null) {
mucOptions.updateUser(parseItem(conversation, item, from)); mucOptions.updateUser(parseItem(conversation, item, from));
} }
MucOptions.User user = mucOptions.deleteUser(from); MucOptions.User user = mucOptions.deleteUser(from);
if (user != null) { if (user != null) {
mXmppConnectionService.getAvatarService().clear(user); mXmppConnectionService.getAvatarService().clear(user);
} }
} }
} else if (type.equals("error")) { } else if (type.equals("error")) {
final Element error = packet.findChild("error"); final Element error = packet.findChild("error");
if (error == null) { if (error == null) {
return; return;
} }
if (error.hasChild("conflict")) { if (error.hasChild("conflict")) {
if (mucOptions.online()) { if (mucOptions.online()) {
invokeRenameListener(mucOptions, false); invokeRenameListener(mucOptions, false);
} else { } else {
mucOptions.setError(MucOptions.Error.NICK_IN_USE); mucOptions.setError(MucOptions.Error.NICK_IN_USE);
} }
} else if (error.hasChild("not-authorized")) { } else if (error.hasChild("not-authorized")) {
mucOptions.setError(MucOptions.Error.PASSWORD_REQUIRED); mucOptions.setError(MucOptions.Error.PASSWORD_REQUIRED);
} else if (error.hasChild("forbidden")) { } else if (error.hasChild("forbidden")) {
mucOptions.setError(MucOptions.Error.BANNED); mucOptions.setError(MucOptions.Error.BANNED);
} else if (error.hasChild("registration-required")) { } else if (error.hasChild("registration-required")) {
mucOptions.setError(MucOptions.Error.MEMBERS_ONLY); mucOptions.setError(MucOptions.Error.MEMBERS_ONLY);
} else if (error.hasChild("resource-constraint")) { } else if (error.hasChild("resource-constraint")) {
mucOptions.setError(MucOptions.Error.RESOURCE_CONSTRAINT); mucOptions.setError(MucOptions.Error.RESOURCE_CONSTRAINT);
} else if (error.hasChild("remote-server-timeout")) { } else if (error.hasChild("remote-server-timeout")) {
mucOptions.setError(MucOptions.Error.REMOTE_SERVER_TIMEOUT); mucOptions.setError(MucOptions.Error.REMOTE_SERVER_TIMEOUT);
} else if (error.hasChild("gone")) { } else if (error.hasChild("gone")) {
final String gone = error.findChildContent("gone"); final String gone = error.findChildContent("gone");
final Jid alternate; final Jid alternate;
if (gone != null) { if (gone != null) {
final XmppUri xmppUri = new XmppUri(gone); final XmppUri xmppUri = new XmppUri(gone);
if (xmppUri.isValidJid()) { if (xmppUri.isValidJid()) {
alternate = xmppUri.getJid(); alternate = xmppUri.getJid();
} else { } else {
alternate = null; alternate = null;
} }
} else { } else {
alternate = null; alternate = null;
} }
mucOptions.setError(MucOptions.Error.DESTROYED); mucOptions.setError(MucOptions.Error.DESTROYED);
if (alternate != null) { if (alternate != null) {
Log.d(Config.LOGTAG, conversation.getAccount().getJid().asBareJid() + ": muc destroyed. alternate location " + alternate); Log.d(
} Config.LOGTAG,
} else { conversation.getAccount().getJid().asBareJid()
final String text = error.findChildContent("text"); + ": muc destroyed. alternate location "
if (text != null && text.contains("attribute 'to'")) { + alternate);
if (mucOptions.online()) { }
invokeRenameListener(mucOptions, false); } else {
} else { final String text = error.findChildContent("text");
mucOptions.setError(MucOptions.Error.INVALID_NICK); if (text != null && text.contains("attribute 'to'")) {
} if (mucOptions.online()) {
} else { invokeRenameListener(mucOptions, false);
mucOptions.setError(MucOptions.Error.UNKNOWN); } else {
Log.d(Config.LOGTAG, "unknown error in conference: " + packet); mucOptions.setError(MucOptions.Error.INVALID_NICK);
} }
} } else {
} mucOptions.setError(MucOptions.Error.UNKNOWN);
} Log.d(Config.LOGTAG, "unknown error in conference: " + packet);
} }
}
}
}
}
private static void invokeRenameListener(final MucOptions options, boolean success) { private static void invokeRenameListener(final MucOptions options, boolean success) {
if (options.onRenameListener != null) { if (options.onRenameListener != null) {
if (success) { if (success) {
options.onRenameListener.onSuccess(); options.onRenameListener.onSuccess();
} else { } else {
options.onRenameListener.onFailure(); options.onRenameListener.onFailure();
} }
options.onRenameListener = null; options.onRenameListener = null;
} }
} }
private static List<String> getStatusCodes(Element x) { private static List<String> getStatusCodes(Element x) {
List<String> codes = new ArrayList<>(); List<String> codes = new ArrayList<>();
if (x != null) { if (x != null) {
for (Element child : x.getChildren()) { for (Element child : x.getChildren()) {
if (child.getName().equals("status")) { if (child.getName().equals("status")) {
String code = child.getAttribute("code"); String code = child.getAttribute("code");
if (code != null) { if (code != null) {
codes.add(code); codes.add(code);
} }
} }
} }
} }
return codes; return codes;
} }
private void parseContactPresence(final PresencePacket packet, final Account account) { private void parseContactPresence(final PresencePacket packet, final Account account) {
final PresenceGenerator mPresenceGenerator = mXmppConnectionService.getPresenceGenerator(); final PresenceGenerator mPresenceGenerator = mXmppConnectionService.getPresenceGenerator();
final Jid from = packet.getFrom(); final Jid from = packet.getFrom();
if (from == null || from.equals(account.getJid())) { if (from == null || from.equals(account.getJid())) {
return; return;
} }
final String type = packet.getAttribute("type"); final String type = packet.getAttribute("type");
final Contact contact = account.getRoster().getContact(from); final Contact contact = account.getRoster().getContact(from);
if (type == null) { if (type == null) {
final String resource = from.isBareJid() ? "" : from.getResource(); final String resource = from.isBareJid() ? "" : from.getResource();
Avatar avatar = Avatar.parsePresence(packet.findChild("x", "vcard-temp:x:update")); final Avatar avatar =
if (avatar != null && (!contact.isSelf() || account.getAvatar() == null)) { Avatar.parsePresence(packet.findChild("x", "vcard-temp:x:update"));
avatar.owner = from.asBareJid(); if (avatar != null && (!contact.isSelf() || account.getAvatar() == null)) {
if (mXmppConnectionService.getFileBackend().isAvatarCached(avatar)) { avatar.owner = from.asBareJid();
if (avatar.owner.equals(account.getJid().asBareJid())) { if (mXmppConnectionService.getFileBackend().isAvatarCached(avatar)) {
account.setAvatar(avatar.getFilename()); if (avatar.owner.equals(account.getJid().asBareJid())) {
mXmppConnectionService.databaseBackend.updateAccount(account); account.setAvatar(avatar.getFilename());
mXmppConnectionService.getAvatarService().clear(account); mXmppConnectionService.databaseBackend.updateAccount(account);
mXmppConnectionService.updateConversationUi(); mXmppConnectionService.getAvatarService().clear(account);
mXmppConnectionService.updateAccountUi(); mXmppConnectionService.updateConversationUi();
} else { mXmppConnectionService.updateAccountUi();
contact.setAvatar(avatar); } else {
mXmppConnectionService.syncRoster(account); contact.setAvatar(avatar);
mXmppConnectionService.getAvatarService().clear(contact); mXmppConnectionService.syncRoster(account);
mXmppConnectionService.updateConversationUi(); mXmppConnectionService.getAvatarService().clear(contact);
mXmppConnectionService.updateRosterUi(); mXmppConnectionService.updateConversationUi();
} mXmppConnectionService.updateRosterUi();
} else if (mXmppConnectionService.isDataSaverDisabled()){ }
mXmppConnectionService.fetchAvatar(account, avatar); } else if (mXmppConnectionService.isDataSaverDisabled()) {
} mXmppConnectionService.fetchAvatar(account, avatar);
} }
}
if (mXmppConnectionService.isMuc(account, from)) { if (mXmppConnectionService.isMuc(account, from)) {
return; return;
} }
int sizeBefore = contact.getPresences().size(); final int sizeBefore = contact.getPresences().size();
final String show = packet.findChildContent("show"); final String show = packet.findChildContent("show");
final Element caps = packet.findChild("c", "http://jabber.org/protocol/caps"); final Element caps = packet.findChild("c", "http://jabber.org/protocol/caps");
final String message = packet.findChildContent("status"); final String message = packet.findChildContent("status");
final Presence presence = Presence.parse(show, caps, message); final Presence presence = Presence.parse(show, caps, message);
contact.updatePresence(resource, presence); contact.updatePresence(resource, presence);
if (presence.hasCaps()) { if (presence.hasCaps()) {
mXmppConnectionService.fetchCaps(account, from, presence); mXmppConnectionService.fetchCaps(account, from, presence);
} }
final Element idle = packet.findChild("idle", Namespace.IDLE); final Element idle = packet.findChild("idle", Namespace.IDLE);
if (idle != null) { if (idle != null) {
try { try {
final String since = idle.getAttribute("since"); final String since = idle.getAttribute("since");
contact.setLastseen(AbstractParser.parseTimestamp(since)); contact.setLastseen(AbstractParser.parseTimestamp(since));
contact.flagInactive(); contact.flagInactive();
} catch (Throwable throwable) { } catch (Throwable throwable) {
if (contact.setLastseen(AbstractParser.parseTimestamp(packet))) { if (contact.setLastseen(AbstractParser.parseTimestamp(packet))) {
contact.flagActive(); contact.flagActive();
} }
} }
} else { } else {
if (contact.setLastseen(AbstractParser.parseTimestamp(packet))) { if (contact.setLastseen(AbstractParser.parseTimestamp(packet))) {
contact.flagActive(); contact.flagActive();
} }
} }
PgpEngine pgp = mXmppConnectionService.getPgpEngine(); final PgpEngine pgp = mXmppConnectionService.getPgpEngine();
Element x = packet.findChild("x", "jabber:x:signed"); final Element x = packet.findChild("x", "jabber:x:signed");
if (pgp != null && x != null) { if (pgp != null && x != null) {
final String status = packet.findChildContent("status"); final String status = packet.findChildContent("status");
final long keyId = pgp.fetchKeyId(account, status, x.getContent()); final long keyId = pgp.fetchKeyId(account, status, x.getContent());
if (keyId != 0 && contact.setPgpKeyId(keyId)) { if (keyId != 0 && contact.setPgpKeyId(keyId)) {
Log.d(Config.LOGTAG,account.getJid().asBareJid()+": found OpenPGP key id for "+contact.getJid()+" "+OpenPgpUtils.convertKeyIdToHex(keyId)); Log.d(
mXmppConnectionService.syncRoster(account); Config.LOGTAG,
} account.getJid().asBareJid()
} + ": found OpenPGP key id for "
boolean online = sizeBefore < contact.getPresences().size(); + contact.getJid()
mXmppConnectionService.onContactStatusChanged.onContactStatusChanged(contact, online); + " "
} else if (type.equals("unavailable")) { + OpenPgpUtils.convertKeyIdToHex(keyId));
if (contact.setLastseen(AbstractParser.parseTimestamp(packet,0L,true))) { mXmppConnectionService.syncRoster(account);
contact.flagInactive(); }
} }
if (from.isBareJid()) { boolean online = sizeBefore < contact.getPresences().size();
contact.clearPresences(); mXmppConnectionService.onContactStatusChanged.onContactStatusChanged(contact, online);
} else { } else if (type.equals("unavailable")) {
contact.removePresence(from.getResource()); if (contact.setLastseen(AbstractParser.parseTimestamp(packet, 0L, true))) {
} contact.flagInactive();
if (contact.getShownStatus() == Presence.Status.OFFLINE) { }
contact.flagInactive(); if (from.isBareJid()) {
} contact.clearPresences();
mXmppConnectionService.onContactStatusChanged.onContactStatusChanged(contact, false); } else {
} else if (type.equals("subscribe")) { contact.removePresence(from.getResource());
if (contact.setPresenceName(packet.findChildContent("nick", Namespace.NICK))) { }
mXmppConnectionService.syncRoster(account); if (contact.getShownStatus() == Presence.Status.OFFLINE) {
mXmppConnectionService.getAvatarService().clear(contact); contact.flagInactive();
} }
if (contact.getOption(Contact.Options.PREEMPTIVE_GRANT)) { mXmppConnectionService.onContactStatusChanged.onContactStatusChanged(contact, false);
mXmppConnectionService.sendPresencePacket(account, } else if (type.equals("subscribe")) {
mPresenceGenerator.sendPresenceUpdatesTo(contact)); if (contact.isBlocked()) {
} else { Log.d(
contact.setOption(Contact.Options.PENDING_SUBSCRIPTION_REQUEST); Config.LOGTAG,
final Conversation conversation = mXmppConnectionService.findOrCreateConversation( account.getJid().asBareJid()
account, contact.getJid().asBareJid(), false, false); + ": ignoring 'subscribe' presence from blocked "
final String statusMessage = packet.findChildContent("status"); + from);
if (statusMessage != null return;
&& !statusMessage.isEmpty() }
&& conversation.countMessages() == 0) { if (contact.setPresenceName(packet.findChildContent("nick", Namespace.NICK))) {
conversation.add(new Message( mXmppConnectionService.syncRoster(account);
conversation, mXmppConnectionService.getAvatarService().clear(contact);
statusMessage, }
Message.ENCRYPTION_NONE, if (contact.getOption(Contact.Options.PREEMPTIVE_GRANT)) {
Message.STATUS_RECEIVED mXmppConnectionService.sendPresencePacket(
)); account, mPresenceGenerator.sendPresenceUpdatesTo(contact));
} } else {
} contact.setOption(Contact.Options.PENDING_SUBSCRIPTION_REQUEST);
} final Conversation conversation =
mXmppConnectionService.updateRosterUi(); mXmppConnectionService.findOrCreateConversation(
} account, contact.getJid().asBareJid(), false, false);
final String statusMessage = packet.findChildContent("status");
if (statusMessage != null
&& !statusMessage.isEmpty()
&& conversation.countMessages() == 0) {
conversation.add(
new Message(
conversation,
statusMessage,
Message.ENCRYPTION_NONE,
Message.STATUS_RECEIVED));
}
}
}
mXmppConnectionService.updateRosterUi();
}
@Override @Override
public void onPresencePacketReceived(Account account, PresencePacket packet) { public void onPresencePacketReceived(Account account, PresencePacket packet) {
if (packet.hasChild("x", Namespace.MUC_USER)) { if (packet.hasChild("x", Namespace.MUC_USER)) {
this.parseConferencePresence(packet, account); this.parseConferencePresence(packet, account);
} else if (packet.hasChild("x", "http://jabber.org/protocol/muc")) { } else if (packet.hasChild("x", "http://jabber.org/protocol/muc")) {
this.parseConferencePresence(packet, account); this.parseConferencePresence(packet, account);
} else if ("error".equals(packet.getAttribute("type")) && mXmppConnectionService.isMuc(account, packet.getFrom())) { } else if ("error".equals(packet.getAttribute("type"))
this.parseConferencePresence(packet, account); && mXmppConnectionService.isMuc(account, packet.getFrom())) {
} else { this.parseConferencePresence(packet, account);
this.parseContactPresence(packet, account); } else {
} this.parseContactPresence(packet, account);
} }
}
} }