diff options
19 files changed, 318 insertions, 239 deletions
diff --git a/src/main/java/de/thedevstack/conversationsplus/generator/IqGenerator.java b/src/main/java/de/thedevstack/conversationsplus/generator/IqGenerator.java index 3d3dd360..7409b4fd 100644 --- a/src/main/java/de/thedevstack/conversationsplus/generator/IqGenerator.java +++ b/src/main/java/de/thedevstack/conversationsplus/generator/IqGenerator.java @@ -52,7 +52,7 @@ public class IqGenerator extends AbstractGenerator { return packet; } - protected IqPacket retrieve(String node, Element item) { + protected static IqPacket retrieve(String node, Element item) { final IqPacket packet = new IqPacket(IqPacket.TYPE.GET); final Element pubsub = packet.addChild("pubsub", "http://jabber.org/protocol/pubsub"); @@ -86,7 +86,7 @@ public class IqGenerator extends AbstractGenerator { return publish("urn:xmpp:avatar:metadata", item); } - public IqPacket retrievePepAvatar(final Avatar avatar) { + public static IqPacket retrievePepAvatar(final Avatar avatar) { final Element item = new Element("item"); item.setAttribute("id", avatar.sha1sum); final IqPacket packet = retrieve("urn:xmpp:avatar:data", item); @@ -94,14 +94,14 @@ public class IqGenerator extends AbstractGenerator { return packet; } - public IqPacket retrieveVcardAvatar(final Avatar avatar) { + public static IqPacket retrieveVcardAvatar(final Avatar avatar) { final IqPacket packet = new IqPacket(IqPacket.TYPE.GET); packet.setTo(avatar.owner); packet.addChild("vCard", "vcard-temp"); return packet; } - public IqPacket retrieveAvatarMetaData(final Jid to) { + public static IqPacket retrieveAvatarMetaData(final Jid to) { final IqPacket packet = retrieve("urn:xmpp:avatar:metadata", null); if (to != null) { packet.setTo(to); diff --git a/src/main/java/de/thedevstack/conversationsplus/parser/AbstractParser.java b/src/main/java/de/thedevstack/conversationsplus/parser/AbstractParser.java index c9efe3d7..fe6522a3 100644 --- a/src/main/java/de/thedevstack/conversationsplus/parser/AbstractParser.java +++ b/src/main/java/de/thedevstack/conversationsplus/parser/AbstractParser.java @@ -5,15 +5,11 @@ import java.text.SimpleDateFormat; import java.util.Date; import java.util.Locale; -import javax.xml.datatype.DatatypeConfigurationException; -import javax.xml.datatype.DatatypeFactory; - import de.thedevstack.conversationsplus.entities.Account; import de.thedevstack.conversationsplus.entities.Contact; import de.thedevstack.conversationsplus.services.XmppConnectionService; import de.thedevstack.conversationsplus.xml.Element; import de.thedevstack.conversationsplus.xmpp.jid.Jid; -import de.thedevstack.conversationsplus.xmpp.stanzas.MessagePacket; public abstract class AbstractParser { @@ -26,7 +22,7 @@ public abstract class AbstractParser { /** * Gets the timestamp from the 'delay' element. * Refer to XEP-0203: Delayed Delivery for details. @link{http://xmpp.org/extensions/xep-0203.html} - * @param packet the element to find the child element 'delay' in. + * @param element the element to find the child element 'delay' in. * @return the time in milli seconds of the attribute 'stamp' of the * element 'delay'. In case there is no 'delay' element or no 'stamp' * attribute or the current time is less than the value of the 'stamp' @@ -92,7 +88,7 @@ public abstract class AbstractParser { } } - protected String avatarData(Element items) { + protected static String avatarData(Element items) { Element item = items.findChild("item"); if (item == null) { return null; diff --git a/src/main/java/de/thedevstack/conversationsplus/parser/IqParser.java b/src/main/java/de/thedevstack/conversationsplus/parser/IqParser.java index 9df70c1e..fc764a88 100644 --- a/src/main/java/de/thedevstack/conversationsplus/parser/IqParser.java +++ b/src/main/java/de/thedevstack/conversationsplus/parser/IqParser.java @@ -7,6 +7,7 @@ import de.thedevstack.android.logcat.Logging; import de.thedevstack.conversationsplus.Config; import de.thedevstack.conversationsplus.entities.Account; import de.thedevstack.conversationsplus.entities.Contact; +import de.thedevstack.conversationsplus.services.AvatarService; import de.thedevstack.conversationsplus.services.XmppConnectionService; import de.thedevstack.conversationsplus.utils.Xmlns; import de.thedevstack.conversationsplus.xml.Element; @@ -50,14 +51,14 @@ public class IqParser extends AbstractParser implements OnIqPacketReceived { contact.parseSubscriptionFromElement(item); } } - mXmppConnectionService.getAvatarService().clear(contact); + AvatarService.getInstance().clear(contact); } } mXmppConnectionService.updateConversationUi(); mXmppConnectionService.updateRosterUi(); } - public String avatarData(final IqPacket packet) { + public static String avatarData(final IqPacket packet) { final Element pubsub = packet.findChild("pubsub", "http://jabber.org/protocol/pubsub"); if (pubsub == null) { @@ -67,7 +68,7 @@ public class IqParser extends AbstractParser implements OnIqPacketReceived { if (items == null) { return null; } - return super.avatarData(items); + return AbstractParser.avatarData(items); } @Override diff --git a/src/main/java/de/thedevstack/conversationsplus/parser/MessageParser.java b/src/main/java/de/thedevstack/conversationsplus/parser/MessageParser.java index 721f1a23..85c38e12 100644 --- a/src/main/java/de/thedevstack/conversationsplus/parser/MessageParser.java +++ b/src/main/java/de/thedevstack/conversationsplus/parser/MessageParser.java @@ -14,6 +14,7 @@ import de.thedevstack.conversationsplus.entities.Conversation; import de.thedevstack.conversationsplus.entities.Message; import de.thedevstack.conversationsplus.entities.MucOptions; import de.thedevstack.conversationsplus.http.HttpConnectionManager; +import de.thedevstack.conversationsplus.services.AvatarService; import de.thedevstack.conversationsplus.services.MessageArchiveService; import de.thedevstack.conversationsplus.services.XmppConnectionService; import de.thedevstack.conversationsplus.utils.AvatarUtil; @@ -148,18 +149,18 @@ public class MessageParser extends AbstractParser implements if (account.setAvatar(avatar.getFilename())) { mXmppConnectionService.databaseBackend.updateAccount(account); } - mXmppConnectionService.getAvatarService().clear(account); + AvatarService.getInstance().clear(account); mXmppConnectionService.updateConversationUi(); mXmppConnectionService.updateAccountUi(); } else { Contact contact = account.getRoster().getContact(from); contact.setAvatar(avatar); - mXmppConnectionService.getAvatarService().clear(contact); + AvatarService.getInstance().clear(contact); mXmppConnectionService.updateConversationUi(); mXmppConnectionService.updateRosterUi(); } } else { - mXmppConnectionService.fetchAvatar(account, avatar); + AvatarService.getInstance().fetchAvatar(account, avatar); } } } else if ("http://jabber.org/protocol/nick".equals(node)) { @@ -168,7 +169,7 @@ public class MessageParser extends AbstractParser implements if (nick != null) { Contact contact = account.getRoster().getContact(from); contact.setPresenceName(nick.getContent()); - mXmppConnectionService.getAvatarService().clear(account); + AvatarService.getInstance().clear(account); mXmppConnectionService.updateConversationUi(); mXmppConnectionService.updateAccountUi(); } diff --git a/src/main/java/de/thedevstack/conversationsplus/parser/PresenceParser.java b/src/main/java/de/thedevstack/conversationsplus/parser/PresenceParser.java index ce52bbeb..8bc5ec89 100644 --- a/src/main/java/de/thedevstack/conversationsplus/parser/PresenceParser.java +++ b/src/main/java/de/thedevstack/conversationsplus/parser/PresenceParser.java @@ -9,8 +9,10 @@ import de.thedevstack.conversationsplus.entities.Conversation; import de.thedevstack.conversationsplus.entities.MucOptions; import de.thedevstack.conversationsplus.entities.Presences; import de.thedevstack.conversationsplus.generator.PresenceGenerator; +import de.thedevstack.conversationsplus.services.AvatarService; import de.thedevstack.conversationsplus.services.XmppConnectionService; import de.thedevstack.conversationsplus.utils.AvatarUtil; +import de.thedevstack.conversationsplus.utils.UiUpdateHelper; import de.thedevstack.conversationsplus.xml.Element; import de.thedevstack.conversationsplus.xmpp.OnPresencePacketReceived; import de.thedevstack.conversationsplus.xmpp.jid.Jid; @@ -35,12 +37,12 @@ public class PresenceParser extends AbstractParser implements mucOptions.processPacket(packet, mPgpEngine); final ArrayList<MucOptions.User> tileUserAfter = new ArrayList<>(mucOptions.getUsers().subList(0,Math.min(mucOptions.getUsers().size(),5))); if (!tileUserAfter.equals(tileUserBefore)) { - mXmppConnectionService.getAvatarService().clear(conversation); + AvatarService.getInstance().clear(conversation); } if (before != mucOptions.online() || (mucOptions.online() && count != mucOptions.getUsers().size())) { - mXmppConnectionService.updateConversationUi(); + UiUpdateHelper.updateConversationUi(); } else if (mucOptions.online()) { - mXmppConnectionService.updateMucRosterUi(); + UiUpdateHelper.updateMucRosterUi(); } } } @@ -61,12 +63,12 @@ public class PresenceParser extends AbstractParser implements avatar.owner = from.toBareJid(); if (AvatarUtil.isAvatarCached(avatar)) { if (contact.setAvatar(avatar)) { - mXmppConnectionService.getAvatarService().clear(contact); - mXmppConnectionService.updateConversationUi(); - mXmppConnectionService.updateRosterUi(); + AvatarService.getInstance().clear(contact); + UiUpdateHelper.updateConversationUi(); + UiUpdateHelper.updateRosterUi(); } } else { - mXmppConnectionService.fetchAvatar(account, avatar); + AvatarService.getInstance().fetchAvatar(account, avatar); } } int sizeBefore = contact.getPresences().size(); @@ -96,7 +98,7 @@ public class PresenceParser extends AbstractParser implements contact.setOption(Contact.Options.PENDING_SUBSCRIPTION_REQUEST); } } - mXmppConnectionService.updateRosterUi(); + UiUpdateHelper.updateRosterUi(); } @Override diff --git a/src/main/java/de/thedevstack/conversationsplus/services/AvatarService.java b/src/main/java/de/thedevstack/conversationsplus/services/AvatarService.java index 83aa83e3..710d5bbd 100644 --- a/src/main/java/de/thedevstack/conversationsplus/services/AvatarService.java +++ b/src/main/java/de/thedevstack/conversationsplus/services/AvatarService.java @@ -8,18 +8,32 @@ import android.graphics.Typeface; import android.net.Uri; import java.util.ArrayList; +import java.util.Iterator; import java.util.List; import java.util.Locale; +import de.thedevstack.android.logcat.Logging; +import de.thedevstack.conversationsplus.Config; +import de.thedevstack.conversationsplus.ConversationsPlusApplication; import de.thedevstack.conversationsplus.entities.Account; import de.thedevstack.conversationsplus.entities.Bookmark; import de.thedevstack.conversationsplus.entities.Contact; import de.thedevstack.conversationsplus.entities.Conversation; import de.thedevstack.conversationsplus.entities.ListItem; import de.thedevstack.conversationsplus.entities.MucOptions; +import de.thedevstack.conversationsplus.generator.IqGenerator; +import de.thedevstack.conversationsplus.parser.IqParser; +import de.thedevstack.conversationsplus.persistance.DatabaseBackend; +import de.thedevstack.conversationsplus.ui.UiCallback; import de.thedevstack.conversationsplus.utils.AvatarUtil; import de.thedevstack.conversationsplus.utils.ImageUtil; import de.thedevstack.conversationsplus.utils.UIHelper; +import de.thedevstack.conversationsplus.utils.UiUpdateHelper; +import de.thedevstack.conversationsplus.utils.XmppSendUtil; +import de.thedevstack.conversationsplus.xml.Element; +import de.thedevstack.conversationsplus.xmpp.OnIqPacketReceived; +import de.thedevstack.conversationsplus.xmpp.pep.Avatar; +import de.thedevstack.conversationsplus.xmpp.stanzas.IqPacket; public class AvatarService { @@ -31,14 +45,14 @@ public class AvatarService { private static final String PREFIX_CONVERSATION = "conversation"; private static final String PREFIX_ACCOUNT = "account"; private static final String PREFIX_GENERIC = "generic"; + private static final AvatarService INSTANCE = new AvatarService(); - final private ArrayList<Integer> sizes = new ArrayList<>(); - - protected XmppConnectionService mXmppConnectionService = null; - - public AvatarService(XmppConnectionService service) { - this.mXmppConnectionService = service; - } + final private ArrayList<Integer> sizes = new ArrayList<>(); + private final List<String> mInProgressAvatarFetches = new ArrayList<>(); + + public static AvatarService getInstance() { + return INSTANCE; + } private Bitmap get(final Contact contact, final int size, boolean cachedOnly) { final String KEY = key(contact, size); @@ -255,7 +269,7 @@ public class AvatarService { textPaint.getTextBounds(letter, 0, 1, rect); float width = textPaint.measureText(letter); canvas.drawText(letter, (right + left) / 2 - width / 2, (top + bottom) - / 2 + rect.height() / 2, textPaint); + / 2 + rect.height() / 2, textPaint); } private void drawTile(Canvas canvas, MucOptions.User user, int left, @@ -288,4 +302,163 @@ public class AvatarService { canvas.drawBitmap(bm, null, dst, null); } + private static String generateFetchKey(Account account, final Avatar avatar) { + return account.getJid().toBareJid()+"_"+avatar.owner+"_"+avatar.sha1sum; + } + + public void fetchAvatar(Account account, final Avatar avatar, final UiCallback<Avatar> callback) { + final String KEY = generateFetchKey(account, avatar); + synchronized(this.mInProgressAvatarFetches) { + if (this.mInProgressAvatarFetches.contains(KEY)) { + return; + } else { + switch (avatar.origin) { + case PEP: + this.mInProgressAvatarFetches.add(KEY); + fetchAvatarPep(account, avatar, callback); + break; + case VCARD: + this.mInProgressAvatarFetches.add(KEY); + fetchAvatarVcard(account, avatar, callback); + break; + } + } + } + } + + private void fetchAvatarPep(final Account account, final Avatar avatar, final UiCallback<Avatar> callback) { + IqPacket packet = IqGenerator.retrievePepAvatar(avatar); + XmppSendUtil.sendIqPacket(account, packet, new OnIqPacketReceived() { + + @Override + public void onIqPacketReceived(Account account, IqPacket result) { + synchronized (mInProgressAvatarFetches) { + mInProgressAvatarFetches.remove(generateFetchKey(account, avatar)); + } + final String ERROR = account.getJid().toBareJid() + + ": fetching avatar for " + avatar.owner + " failed "; + if (result.getType() == IqPacket.TYPE.RESULT) { + avatar.image = IqParser.avatarData(result); + if (avatar.image != null) { + if (AvatarUtil.save(avatar)) { + if (account.getJid().toBareJid().equals(avatar.owner)) { + if (account.setAvatar(avatar.getFilename())) { + DatabaseBackend.getInstance(ConversationsPlusApplication.getAppContext()).updateAccount(account); + } + AvatarService.this.clear(account); + UiUpdateHelper.updateConversationUi(); + UiUpdateHelper.updateAccountUi(); + } else { + Contact contact = account.getRoster() + .getContact(avatar.owner); + contact.setAvatar(avatar); + AvatarService.this.clear(contact); + UiUpdateHelper.updateConversationUi(); + UiUpdateHelper.updateRosterUi(); + } + if (callback != null) { + callback.success(avatar); + } + Logging.d(Config.LOGTAG, account.getJid().toBareJid() + + ": succesfuly fetched pep avatar for " + avatar.owner); + return; + } + } else { + + Logging.d(Config.LOGTAG, ERROR + "(parsing error)"); + } + } else { + Element error = result.findChild("error"); + if (error == null) { + Logging.d(Config.LOGTAG, ERROR + "(server error)"); + } else { + Logging.d(Config.LOGTAG, ERROR + error.toString()); + } + } + if (callback != null) { + callback.error(0, null); + } + + } + }); + } + + private void fetchAvatarVcard(final Account account, final Avatar avatar, final UiCallback<Avatar> callback) { + IqPacket packet = IqGenerator.retrieveVcardAvatar(avatar); + XmppSendUtil.sendIqPacket(account, packet, new OnIqPacketReceived() { + @Override + public void onIqPacketReceived(Account account, IqPacket packet) { + synchronized (mInProgressAvatarFetches) { + mInProgressAvatarFetches.remove(generateFetchKey(account, avatar)); + } + if (packet.getType() == IqPacket.TYPE.RESULT) { + Element vCard = packet.findChild("vCard", "vcard-temp"); + Element photo = vCard != null ? vCard.findChild("PHOTO") : null; + String image = photo != null ? photo.findChildContent("BINVAL") : null; + if (image != null) { + avatar.image = image; + if (AvatarUtil.save(avatar)) { + Logging.d(Config.LOGTAG, account.getJid().toBareJid() + + ": successfully fetched vCard avatar for " + avatar.owner); + Contact contact = account.getRoster() + .getContact(avatar.owner); + contact.setAvatar(avatar); + AvatarService.this.clear(contact); + UiUpdateHelper.updateConversationUi(); + UiUpdateHelper.updateRosterUi(); + } + } + } + } + }); + } + + public void checkForAvatar(Account account, final UiCallback<Avatar> callback) { + IqPacket packet = IqGenerator.retrieveAvatarMetaData(null); + XmppSendUtil.sendIqPacket(account, packet, new OnIqPacketReceived() { + + @Override + public void onIqPacketReceived(Account account, IqPacket packet) { + if (packet.getType() == IqPacket.TYPE.RESULT) { + Element pubsub = packet.findChild("pubsub", + "http://jabber.org/protocol/pubsub"); + if (pubsub != null) { + Element items = pubsub.findChild("items"); + if (items != null) { + Avatar avatar = Avatar.parseMetadata(items); + if (avatar != null) { + avatar.owner = account.getJid().toBareJid(); + if (AvatarUtil.isAvatarCached(avatar)) { + if (account.setAvatar(avatar.getFilename())) { + DatabaseBackend.getInstance(ConversationsPlusApplication.getAppContext()).updateAccount(account); + } + AvatarService.this.clear(account); + callback.success(avatar); + } else { + fetchAvatarPep(account, avatar, callback); + } + return; + } + } + } + } + callback.error(0, null); + } + }); + } + + public void fetchAvatar(Account account, Avatar avatar) { + fetchAvatar(account, avatar, null); + } + + public void clearFetchInProgress(Account account) { + synchronized (this.mInProgressAvatarFetches) { + for(Iterator<String> iterator = this.mInProgressAvatarFetches.iterator(); iterator.hasNext();) { + final String KEY = iterator.next(); + if (KEY.startsWith(account.getJid().toBareJid()+"_")) { + iterator.remove(); + } + } + } + } } diff --git a/src/main/java/de/thedevstack/conversationsplus/services/NotificationService.java b/src/main/java/de/thedevstack/conversationsplus/services/NotificationService.java index 9183e70c..d537ff73 100644 --- a/src/main/java/de/thedevstack/conversationsplus/services/NotificationService.java +++ b/src/main/java/de/thedevstack/conversationsplus/services/NotificationService.java @@ -256,8 +256,7 @@ public class NotificationService { final ArrayList<Message> messages = notifications.values().iterator().next(); if (messages.size() >= 1) { final Conversation conversation = messages.get(0).getConversation(); - mBuilder.setLargeIcon(mXmppConnectionService.getAvatarService() - .get(conversation, getPixel(64))); + mBuilder.setLargeIcon(AvatarService.getInstance().get(conversation, getPixel(64))); mBuilder.setContentTitle(conversation.getName()); Message message; if ((message = getImage(messages)) != null) { diff --git a/src/main/java/de/thedevstack/conversationsplus/services/XmppConnectionService.java b/src/main/java/de/thedevstack/conversationsplus/services/XmppConnectionService.java index 7472ad21..5f800b53 100644 --- a/src/main/java/de/thedevstack/conversationsplus/services/XmppConnectionService.java +++ b/src/main/java/de/thedevstack/conversationsplus/services/XmppConnectionService.java @@ -8,7 +8,6 @@ import android.content.Context; import android.content.Intent; import android.database.ContentObserver; import android.graphics.Bitmap; -import android.graphics.BitmapFactory; import android.net.ConnectivityManager; import android.net.NetworkInfo; import android.net.Uri; @@ -31,9 +30,6 @@ import net.java.otr4j.session.SessionStatus; import org.openintents.openpgp.util.OpenPgpApi; import org.openintents.openpgp.util.OpenPgpServiceConnection; -import java.io.FileNotFoundException; -import java.io.IOException; -import java.io.InputStream; import java.math.BigInteger; import java.security.SecureRandom; import java.util.ArrayList; @@ -42,7 +38,6 @@ import java.util.Collection; import java.util.Collections; import java.util.Comparator; import java.util.Hashtable; -import java.util.Iterator; import java.util.List; import java.util.Locale; import java.util.Map; @@ -53,13 +48,13 @@ import de.duenndns.ssl.MemorizingTrustManager; import de.thedevstack.android.logcat.Logging; import de.thedevstack.conversationsplus.ConversationsPlusApplication; import de.thedevstack.conversationsplus.ConversationsPlusPreferences; -import de.thedevstack.conversationsplus.entities.DownloadableFile; import de.thedevstack.conversationsplus.exceptions.FileCopyException; -import de.thedevstack.conversationsplus.exceptions.UiException; import de.thedevstack.conversationsplus.utils.AvatarUtil; import de.thedevstack.conversationsplus.utils.FileHelper; import de.thedevstack.conversationsplus.utils.ImageUtil; import de.thedevstack.conversationsplus.utils.MessageUtil; +import de.thedevstack.conversationsplus.utils.UiUpdateHelper; +import de.thedevstack.conversationsplus.utils.XmppSendUtil; import de.tzur.conversations.Settings; import de.thedevstack.conversationsplus.Config; import de.thedevstack.conversationsplus.R; @@ -235,8 +230,6 @@ public class XmppConnectionService extends Service implements OnPhoneContactsLoa this); private HttpConnectionManager mHttpConnectionManager = new HttpConnectionManager( this); - private AvatarService mAvatarService = new AvatarService(this); - private final List<String> mInProgressAvatarFetches = new ArrayList<>(); private MessageArchiveService mMessageArchiveService = new MessageArchiveService(this); private OnConversationUpdate mOnConversationUpdate = null; private int convChangedListenerCount = 0; @@ -337,10 +330,6 @@ public class XmppConnectionService extends Service implements OnPhoneContactsLoa } - public AvatarService getAvatarService() { - return this.mAvatarService; - } - public void attachLocationToConversation(final Conversation conversation, final Uri uri, final UiCallback<Message> callback) { @@ -589,6 +578,7 @@ public class XmppConnectionService extends Service implements OnPhoneContactsLoa this.wakeLock = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK,"XmppConnectionService"); toggleForegroundService(); updateUnreadCountBadge(); + UiUpdateHelper.initXmppConnectionService(this); } public void toggleForegroundService() { @@ -888,7 +878,7 @@ public class XmppConnectionService extends Service implements OnPhoneContactsLoa + phoneContact.getString("lookup"); contact.setSystemAccount(systemAccount); if (contact.setPhotoUri(phoneContact.getString("photouri"))) { - getAvatarService().clear(contact); + AvatarService.getInstance().clear(contact); } contact.setSystemName(phoneContact.getString("displayname")); withSystemAccounts.remove(contact); @@ -897,7 +887,7 @@ public class XmppConnectionService extends Service implements OnPhoneContactsLoa contact.setSystemAccount(null); contact.setSystemName(null); if (contact.setPhotoUri(null)) { - getAvatarService().clear(contact); + AvatarService.getInstance().clear(contact); } } } @@ -1888,7 +1878,7 @@ public class XmppConnectionService extends Service implements OnPhoneContactsLoa IqPacket result) { if (result.getType() == IqPacket.TYPE.RESULT) { if (account.setAvatar(avatar.getFilename())) { - getAvatarService().clear(account); + AvatarService.getInstance().clear(account); databaseBackend.updateAccount(account); } callback.success(avatar); @@ -1911,155 +1901,6 @@ public class XmppConnectionService extends Service implements OnPhoneContactsLoa } } - public void fetchAvatar(Account account, Avatar avatar) { - fetchAvatar(account, avatar, null); - } - - private static String generateFetchKey(Account account, final Avatar avatar) { - return account.getJid().toBareJid()+"_"+avatar.owner+"_"+avatar.sha1sum; - } - - public void fetchAvatar(Account account, final Avatar avatar, final UiCallback<Avatar> callback) { - final String KEY = generateFetchKey(account, avatar); - synchronized(this.mInProgressAvatarFetches) { - if (this.mInProgressAvatarFetches.contains(KEY)) { - return; - } else { - switch (avatar.origin) { - case PEP: - this.mInProgressAvatarFetches.add(KEY); - fetchAvatarPep(account, avatar, callback); - break; - case VCARD: - this.mInProgressAvatarFetches.add(KEY); - fetchAvatarVcard(account, avatar, callback); - break; - } - } - } - } - - private void fetchAvatarPep(Account account, final Avatar avatar, final UiCallback<Avatar> callback) { - IqPacket packet = this.mIqGenerator.retrievePepAvatar(avatar); - sendIqPacket(account, packet, new OnIqPacketReceived() { - - @Override - public void onIqPacketReceived(Account account, IqPacket result) { - synchronized (mInProgressAvatarFetches) { - mInProgressAvatarFetches.remove(generateFetchKey(account, avatar)); - } - final String ERROR = account.getJid().toBareJid() - + ": fetching avatar for " + avatar.owner + " failed "; - if (result.getType() == IqPacket.TYPE.RESULT) { - avatar.image = mIqParser.avatarData(result); - if (avatar.image != null) { - if (AvatarUtil.save(avatar)) { - if (account.getJid().toBareJid().equals(avatar.owner)) { - if (account.setAvatar(avatar.getFilename())) { - databaseBackend.updateAccount(account); - } - getAvatarService().clear(account); - updateConversationUi(); - updateAccountUi(); - } else { - Contact contact = account.getRoster() - .getContact(avatar.owner); - contact.setAvatar(avatar); - getAvatarService().clear(contact); - updateConversationUi(); - updateRosterUi(); - } - if (callback != null) { - callback.success(avatar); - } - Logging.d(Config.LOGTAG, account.getJid().toBareJid() - + ": succesfuly fetched pep avatar for " + avatar.owner); - return; - } - } else { - - Logging.d(Config.LOGTAG, ERROR + "(parsing error)"); - } - } else { - Element error = result.findChild("error"); - if (error == null) { - Logging.d(Config.LOGTAG, ERROR + "(server error)"); - } else { - Logging.d(Config.LOGTAG, ERROR + error.toString()); - } - } - if (callback != null) { - callback.error(0, null); - } - - } - }); - } - - private void fetchAvatarVcard(final Account account, final Avatar avatar, final UiCallback<Avatar> callback) { - IqPacket packet = this.mIqGenerator.retrieveVcardAvatar(avatar); - this.sendIqPacket(account, packet, new OnIqPacketReceived() { - @Override - public void onIqPacketReceived(Account account, IqPacket packet) { - synchronized (mInProgressAvatarFetches) { - mInProgressAvatarFetches.remove(generateFetchKey(account, avatar)); - } - if (packet.getType() == IqPacket.TYPE.RESULT) { - Element vCard = packet.findChild("vCard", "vcard-temp"); - Element photo = vCard != null ? vCard.findChild("PHOTO") : null; - String image = photo != null ? photo.findChildContent("BINVAL") : null; - if (image != null) { - avatar.image = image; - if (AvatarUtil.save(avatar)) { - Logging.d(Config.LOGTAG, account.getJid().toBareJid() - + ": successfully fetched vCard avatar for " + avatar.owner); - Contact contact = account.getRoster() - .getContact(avatar.owner); - contact.setAvatar(avatar); - getAvatarService().clear(contact); - updateConversationUi(); - updateRosterUi(); - } - } - } - } - }); - } - - public void checkForAvatar(Account account, final UiCallback<Avatar> callback) { - IqPacket packet = this.mIqGenerator.retrieveAvatarMetaData(null); - this.sendIqPacket(account, packet, new OnIqPacketReceived() { - - @Override - public void onIqPacketReceived(Account account, IqPacket packet) { - if (packet.getType() == IqPacket.TYPE.RESULT) { - Element pubsub = packet.findChild("pubsub", - "http://jabber.org/protocol/pubsub"); - if (pubsub != null) { - Element items = pubsub.findChild("items"); - if (items != null) { - Avatar avatar = Avatar.parseMetadata(items); - if (avatar != null) { - avatar.owner = account.getJid().toBareJid(); - if (AvatarUtil.isAvatarCached(avatar)) { - if (account.setAvatar(avatar.getFilename())) { - databaseBackend.updateAccount(account); - } - getAvatarService().clear(account); - callback.success(avatar); - } else { - fetchAvatarPep(account, avatar, callback); - } - return; - } - } - } - } - callback.error(0, null); - } - }); - } - public void deleteContactOnServer(Contact contact) { contact.resetOption(Contact.Options.PREEMPTIVE_GRANT); contact.resetOption(Contact.Options.DIRTY_PUSH); @@ -2085,14 +1926,7 @@ public class XmppConnectionService extends Service implements OnPhoneContactsLoa } if (!account.isOptionSet(Account.OPTION_DISABLED)) { - synchronized (this.mInProgressAvatarFetches) { - for(Iterator<String> iterator = this.mInProgressAvatarFetches.iterator(); iterator.hasNext();) { - final String KEY = iterator.next(); - if (KEY.startsWith(account.getJid().toBareJid()+"_")) { - iterator.remove(); - } - } - } + AvatarService.getInstance().clearFetchInProgress(account); if (account.getXmppConnection() == null) { account.setXmppConnection(createConnection(account)); @@ -2354,17 +2188,11 @@ public class XmppConnectionService extends Service implements OnPhoneContactsLoa } public void sendPresencePacket(Account account, PresencePacket packet) { - XmppConnection connection = account.getXmppConnection(); - if (connection != null) { - connection.sendPresencePacket(packet); - } + XmppSendUtil.sendPresencePacket(account, packet); } public void sendIqPacket(final Account account, final IqPacket packet, final OnIqPacketReceived callback) { - final XmppConnection connection = account.getXmppConnection(); - if (connection != null) { - connection.sendIqPacket(packet, callback); - } + XmppSendUtil.sendIqPacket(account, packet, callback); } public void sendPresence(final Account account) { diff --git a/src/main/java/de/thedevstack/conversationsplus/ui/ConferenceDetailsActivity.java b/src/main/java/de/thedevstack/conversationsplus/ui/ConferenceDetailsActivity.java index de6436d9..518041f2 100644 --- a/src/main/java/de/thedevstack/conversationsplus/ui/ConferenceDetailsActivity.java +++ b/src/main/java/de/thedevstack/conversationsplus/ui/ConferenceDetailsActivity.java @@ -36,6 +36,7 @@ import de.thedevstack.conversationsplus.entities.Contact; import de.thedevstack.conversationsplus.entities.Conversation; import de.thedevstack.conversationsplus.entities.MucOptions; import de.thedevstack.conversationsplus.entities.MucOptions.User; +import de.thedevstack.conversationsplus.services.AvatarService; import de.thedevstack.conversationsplus.services.XmppConnectionService; import de.thedevstack.conversationsplus.services.XmppConnectionService.OnMucRosterUpdate; import de.thedevstack.conversationsplus.services.XmppConnectionService.OnConversationUpdate; @@ -405,7 +406,7 @@ public class ConferenceDetailsActivity extends XmppActivity implements OnConvers final User self = mucOptions.getSelf(); mAccountJid.setText(getString(R.string.using_account, mConversation .getAccount().getJid().toBareJid())); - mYourPhoto.setImageBitmap(avatarService().get(mConversation.getAccount(), getPixel(48))); + mYourPhoto.setImageBitmap(AvatarService.getInstance().get(mConversation.getAccount(), getPixel(48))); setTitle(mConversation.getName()); mFullJid.setText(mConversation.getJid().toBareJid().toString()); mYourNick.setText(mucOptions.getActualNick()); @@ -468,11 +469,11 @@ public class ConferenceDetailsActivity extends XmppActivity implements OnConvers Bitmap bm; Contact contact = user.getContact(); if (contact != null) { - bm = avatarService().get(contact, getPixel(48)); + bm = AvatarService.getInstance().get(contact, getPixel(48)); tvDisplayName.setText(contact.getDisplayName()); tvStatus.setText(user.getName() + " \u2022 " + getStatus(user)); } else { - bm = avatarService().get(user.getName(), getPixel(48)); + bm = AvatarService.getInstance().get(user.getName(), getPixel(48)); tvDisplayName.setText(user.getName()); tvStatus.setText(getStatus(user)); diff --git a/src/main/java/de/thedevstack/conversationsplus/ui/ContactDetailsActivity.java b/src/main/java/de/thedevstack/conversationsplus/ui/ContactDetailsActivity.java index e8d822c8..a61d0b4b 100644 --- a/src/main/java/de/thedevstack/conversationsplus/ui/ContactDetailsActivity.java +++ b/src/main/java/de/thedevstack/conversationsplus/ui/ContactDetailsActivity.java @@ -36,6 +36,7 @@ import de.thedevstack.conversationsplus.crypto.PgpEngine; import de.thedevstack.conversationsplus.entities.Account; import de.thedevstack.conversationsplus.entities.Contact; import de.thedevstack.conversationsplus.entities.ListItem; +import de.thedevstack.conversationsplus.services.AvatarService; import de.thedevstack.conversationsplus.services.XmppConnectionService.OnAccountUpdate; import de.thedevstack.conversationsplus.services.XmppConnectionService.OnRosterUpdate; import de.thedevstack.conversationsplus.ui.listeners.ShowResourcesListDialogListener; @@ -351,7 +352,7 @@ public class ContactDetailsActivity extends XmppActivity implements OnAccountUpd } contactJidTv.setOnClickListener(new ShowResourcesListDialogListener(ContactDetailsActivity.this, contact)); accountJidTv.setText(getString(R.string.using_account, contact.getAccount().getJid().toBareJid())); - badge.setImageBitmap(avatarService().get(contact, getPixel(72))); + badge.setImageBitmap(AvatarService.getInstance().get(contact, getPixel(72))); badge.setOnClickListener(this.onBadgeClick); keys.removeAllViews(); diff --git a/src/main/java/de/thedevstack/conversationsplus/ui/EditAccountActivity.java b/src/main/java/de/thedevstack/conversationsplus/ui/EditAccountActivity.java index 822234c7..601ddedc 100644 --- a/src/main/java/de/thedevstack/conversationsplus/ui/EditAccountActivity.java +++ b/src/main/java/de/thedevstack/conversationsplus/ui/EditAccountActivity.java @@ -25,6 +25,7 @@ import android.widget.Toast; import de.thedevstack.conversationsplus.R; import de.thedevstack.conversationsplus.entities.Account; +import de.thedevstack.conversationsplus.services.AvatarService; import de.thedevstack.conversationsplus.services.XmppConnectionService.OnAccountUpdate; import de.thedevstack.conversationsplus.ui.adapter.KnownHostsAdapter; import de.thedevstack.conversationsplus.ui.listeners.ShowResourcesListDialogListener; @@ -157,7 +158,7 @@ public class EditAccountActivity extends XmppActivity implements OnAccountUpdate && mAccount.getStatus() == Account.State.ONLINE) { if (!mFetchingAvatar) { mFetchingAvatar = true; - xmppConnectionService.checkForAvatar(mAccount, + AvatarService.getInstance().checkForAvatar(mAccount, mAvatarFetchCallback); } } else { @@ -427,7 +428,7 @@ public class EditAccountActivity extends XmppActivity implements OnAccountUpdate } if (this.jidToEdit != null) { this.mAvatar.setVisibility(View.VISIBLE); - this.mAvatar.setImageBitmap(avatarService().get(this.mAccount, getPixel(72))); + this.mAvatar.setImageBitmap(AvatarService.getInstance().get(this.mAccount, getPixel(72))); } if (this.mAccount.isOptionSet(Account.OPTION_REGISTER)) { this.mRegisterNew.setVisibility(View.VISIBLE); diff --git a/src/main/java/de/thedevstack/conversationsplus/ui/PublishProfilePictureActivity.java b/src/main/java/de/thedevstack/conversationsplus/ui/PublishProfilePictureActivity.java index 966cc379..f9ab5f03 100644 --- a/src/main/java/de/thedevstack/conversationsplus/ui/PublishProfilePictureActivity.java +++ b/src/main/java/de/thedevstack/conversationsplus/ui/PublishProfilePictureActivity.java @@ -15,6 +15,7 @@ import android.widget.Toast; import de.thedevstack.conversationsplus.R; import de.thedevstack.conversationsplus.entities.Account; +import de.thedevstack.conversationsplus.services.AvatarService; import de.thedevstack.conversationsplus.utils.ImageUtil; import de.thedevstack.conversationsplus.utils.PhoneHelper; import de.thedevstack.conversationsplus.xmpp.jid.InvalidJidException; @@ -171,7 +172,7 @@ public class PublishProfilePictureActivity extends XmppActivity { if (this.avatarUri == null) { if (this.account.getAvatar() != null || this.defaultUri == null) { - this.avatar.setImageBitmap(avatarService().get(account, + this.avatar.setImageBitmap(AvatarService.getInstance().get(account, getPixel(194))); if (this.defaultUri != null) { this.avatar diff --git a/src/main/java/de/thedevstack/conversationsplus/ui/XmppActivity.java b/src/main/java/de/thedevstack/conversationsplus/ui/XmppActivity.java index 23278bfb..40fbe7c1 100644 --- a/src/main/java/de/thedevstack/conversationsplus/ui/XmppActivity.java +++ b/src/main/java/de/thedevstack/conversationsplus/ui/XmppActivity.java @@ -71,7 +71,6 @@ import de.thedevstack.conversationsplus.entities.Conversation; import de.thedevstack.conversationsplus.entities.Message; import de.thedevstack.conversationsplus.entities.MucOptions; import de.thedevstack.conversationsplus.entities.Presences; -import de.thedevstack.conversationsplus.services.AvatarService; import de.thedevstack.conversationsplus.services.XmppConnectionService; import de.thedevstack.conversationsplus.services.XmppConnectionService.XmppConnectionBinder; import de.thedevstack.conversationsplus.utils.ExceptionHelper; @@ -861,10 +860,6 @@ public abstract class XmppActivity extends Activity { } } - public AvatarService avatarService() { - return xmppConnectionService.getAvatarService(); - } - class BitmapWorkerTask extends AsyncTask<Message, Void, Bitmap> { private final WeakReference<ImageView> imageViewReference; private final boolean setSize; diff --git a/src/main/java/de/thedevstack/conversationsplus/ui/adapter/AccountAdapter.java b/src/main/java/de/thedevstack/conversationsplus/ui/adapter/AccountAdapter.java index 08c9a0e1..6195f47b 100644 --- a/src/main/java/de/thedevstack/conversationsplus/ui/adapter/AccountAdapter.java +++ b/src/main/java/de/thedevstack/conversationsplus/ui/adapter/AccountAdapter.java @@ -4,6 +4,7 @@ import java.util.List; import de.thedevstack.conversationsplus.R; import de.thedevstack.conversationsplus.entities.Account; +import de.thedevstack.conversationsplus.services.AvatarService; import de.thedevstack.conversationsplus.ui.XmppActivity; import de.thedevstack.conversationsplus.ui.ManageAccountActivity; import android.content.Context; @@ -37,7 +38,7 @@ public class AccountAdapter extends ArrayAdapter<Account> { jid.setText(account.getJid().toBareJid().toString()); TextView statusView = (TextView) view.findViewById(R.id.account_status); ImageView imageView = (ImageView) view.findViewById(R.id.account_image); - imageView.setImageBitmap(activity.avatarService().get(account, activity.getPixel(48))); + imageView.setImageBitmap(AvatarService.getInstance().get(account, activity.getPixel(48))); statusView.setText(getContext().getString(account.getStatus().getReadableId())); switch (account.getStatus()) { case ONLINE: diff --git a/src/main/java/de/thedevstack/conversationsplus/ui/adapter/ConversationAdapter.java b/src/main/java/de/thedevstack/conversationsplus/ui/adapter/ConversationAdapter.java index 4e361c67..b6d861d4 100644 --- a/src/main/java/de/thedevstack/conversationsplus/ui/adapter/ConversationAdapter.java +++ b/src/main/java/de/thedevstack/conversationsplus/ui/adapter/ConversationAdapter.java @@ -20,8 +20,8 @@ import java.lang.ref.WeakReference; import java.util.List; import java.util.concurrent.RejectedExecutionException; -import de.thedevstack.android.logcat.Logging; import de.thedevstack.conversationsplus.ConversationsPlusPreferences; +import de.thedevstack.conversationsplus.services.AvatarService; import de.thedevstack.conversationsplus.ui.listeners.ShowResourcesListDialogListener; import de.tzur.conversations.Settings; import de.thedevstack.conversationsplus.R; @@ -146,7 +146,7 @@ public class ConversationAdapter extends ArrayAdapter<Conversation> { @Override protected Bitmap doInBackground(Conversation... params) { - return activity.avatarService().get(params[0], activity.getPixel(56)); + return AvatarService.getInstance().get(params[0], activity.getPixel(56)); } @Override @@ -163,7 +163,7 @@ public class ConversationAdapter extends ArrayAdapter<Conversation> { public void loadAvatar(Conversation conversation, ImageView imageView) { if (cancelPotentialWork(conversation, imageView)) { - final Bitmap bm = activity.avatarService().get(conversation, activity.getPixel(56), true); + final Bitmap bm = AvatarService.getInstance().get(conversation, activity.getPixel(56), true); if (bm != null) { imageView.setImageBitmap(bm); imageView.setBackgroundColor(0x00000000); diff --git a/src/main/java/de/thedevstack/conversationsplus/ui/adapter/ListItemAdapter.java b/src/main/java/de/thedevstack/conversationsplus/ui/adapter/ListItemAdapter.java index 3f342528..4ecebd84 100644 --- a/src/main/java/de/thedevstack/conversationsplus/ui/adapter/ListItemAdapter.java +++ b/src/main/java/de/thedevstack/conversationsplus/ui/adapter/ListItemAdapter.java @@ -5,6 +5,7 @@ import java.util.List; import java.util.concurrent.RejectedExecutionException; import de.thedevstack.conversationsplus.ConversationsPlusPreferences; +import de.thedevstack.conversationsplus.services.AvatarService; import de.tzur.conversations.Settings; import de.thedevstack.conversationsplus.R; import de.thedevstack.conversationsplus.entities.ListItem; @@ -110,7 +111,7 @@ public class ListItemAdapter extends ArrayAdapter<ListItem> { @Override protected Bitmap doInBackground(ListItem... params) { - return activity.avatarService().get(params[0], activity.getPixel(48)); + return AvatarService.getInstance().get(params[0], activity.getPixel(48)); } @Override @@ -127,7 +128,7 @@ public class ListItemAdapter extends ArrayAdapter<ListItem> { public void loadAvatar(ListItem item, ImageView imageView) { if (cancelPotentialWork(item, imageView)) { - final Bitmap bm = activity.avatarService().get(item,activity.getPixel(48),true); + final Bitmap bm = AvatarService.getInstance().get(item,activity.getPixel(48),true); if (bm != null) { imageView.setImageBitmap(bm); imageView.setBackgroundColor(0x00000000); diff --git a/src/main/java/de/thedevstack/conversationsplus/ui/adapter/MessageAdapter.java b/src/main/java/de/thedevstack/conversationsplus/ui/adapter/MessageAdapter.java index 9ab7abf0..647ef68d 100644 --- a/src/main/java/de/thedevstack/conversationsplus/ui/adapter/MessageAdapter.java +++ b/src/main/java/de/thedevstack/conversationsplus/ui/adapter/MessageAdapter.java @@ -34,6 +34,7 @@ import de.thedevstack.conversationsplus.entities.DownloadableFile; import de.thedevstack.conversationsplus.entities.Message; import de.thedevstack.conversationsplus.entities.Message.FileParams; import de.thedevstack.conversationsplus.persistance.FileBackend; +import de.thedevstack.conversationsplus.services.AvatarService; import de.thedevstack.conversationsplus.ui.ConversationActivity; import de.thedevstack.conversationsplus.utils.GeoHelper; import de.thedevstack.conversationsplus.utils.UIHelper; @@ -436,8 +437,7 @@ public class MessageAdapter extends ArrayAdapter<Message> { if (type == STATUS) { if (conversation.getMode() == Conversation.MODE_SINGLE) { - viewHolder.contact_picture.setImageBitmap(activity - .avatarService().get(conversation.getContact(), + viewHolder.contact_picture.setImageBitmap(AvatarService.getInstance().get(conversation.getContact(), activity.getPixel(32))); viewHolder.contact_picture.setAlpha(0.5f); viewHolder.status_message.setText(message.getBody()); @@ -446,14 +446,14 @@ public class MessageAdapter extends ArrayAdapter<Message> { } else if (type == RECEIVED) { Contact contact = message.getContact(); if (contact != null) { - viewHolder.contact_picture.setImageBitmap(activity.avatarService().get(contact, activity.getPixel(48))); + viewHolder.contact_picture.setImageBitmap(AvatarService.getInstance().get(contact, activity.getPixel(48))); } else if (conversation.getMode() == Conversation.MODE_MULTI) { - viewHolder.contact_picture.setImageBitmap(activity.avatarService().get( + viewHolder.contact_picture.setImageBitmap(AvatarService.getInstance().get( UIHelper.getMessageDisplayName(message), activity.getPixel(48))); } } else if (type == SENT) { - viewHolder.contact_picture.setImageBitmap(activity.avatarService().get(account, activity.getPixel(48))); + viewHolder.contact_picture.setImageBitmap(AvatarService.getInstance().get(account, activity.getPixel(48))); } viewHolder.contact_picture diff --git a/src/main/java/de/thedevstack/conversationsplus/utils/UiUpdateHelper.java b/src/main/java/de/thedevstack/conversationsplus/utils/UiUpdateHelper.java new file mode 100644 index 00000000..7638caad --- /dev/null +++ b/src/main/java/de/thedevstack/conversationsplus/utils/UiUpdateHelper.java @@ -0,0 +1,52 @@ +package de.thedevstack.conversationsplus.utils; + +import de.thedevstack.android.logcat.Logging; +import de.thedevstack.conversationsplus.services.XmppConnectionService; + +/** + * Helper class to avoid passing the xmppConnectionService to everywhere just to update the UI. + * TODO: Make even this helper class work without XmppConnectionService + */ +public class UiUpdateHelper { + private static XmppConnectionService xmppConnectionService; + + public static void initXmppConnectionService(XmppConnectionService xmppConnectionService) { + if (null == UiUpdateHelper.xmppConnectionService) { + UiUpdateHelper.xmppConnectionService = xmppConnectionService; + } else { + Logging.e("UiUpdateHelper", "XMPP Connection Service already instantiated."); + } + } + + public static void updateConversationUi() { + if (null != UiUpdateHelper.xmppConnectionService) { + UiUpdateHelper.xmppConnectionService.updateConversationUi(); + } else { + Logging.e("UiUpdateHelper", "XMPP Connection Service not initialized. Conversation Ui not updated."); + } + } + + public static void updateAccountUi() { + if (null != UiUpdateHelper.xmppConnectionService) { + UiUpdateHelper.xmppConnectionService.updateAccountUi(); + } else { + Logging.e("UiUpdateHelper", "XMPP Connection Service not initialized. Account Ui not updated."); + } + } + + public static void updateRosterUi() { + if (null != UiUpdateHelper.xmppConnectionService) { + UiUpdateHelper.xmppConnectionService.updateRosterUi(); + } else { + Logging.e("UiUpdateHelper", "XMPP Connection Service not initialized. Roster Ui not updated."); + } + } + + public static void updateMucRosterUi() { + if (null != UiUpdateHelper.xmppConnectionService) { + UiUpdateHelper.xmppConnectionService.updateMucRosterUi(); + } else { + Logging.e("UiUpdateHelper", "XMPP Connection Service not initialized. MUC Roster Ui not updated."); + } + } +} diff --git a/src/main/java/de/thedevstack/conversationsplus/utils/XmppSendUtil.java b/src/main/java/de/thedevstack/conversationsplus/utils/XmppSendUtil.java new file mode 100644 index 00000000..eb3c5da4 --- /dev/null +++ b/src/main/java/de/thedevstack/conversationsplus/utils/XmppSendUtil.java @@ -0,0 +1,26 @@ +package de.thedevstack.conversationsplus.utils; + +import de.thedevstack.conversationsplus.entities.Account; +import de.thedevstack.conversationsplus.xmpp.OnIqPacketReceived; +import de.thedevstack.conversationsplus.xmpp.XmppConnection; +import de.thedevstack.conversationsplus.xmpp.stanzas.IqPacket; +import de.thedevstack.conversationsplus.xmpp.stanzas.PresencePacket; + +/** + * Created by tzur on 09.01.2016. + */ +public class XmppSendUtil { + public static void sendIqPacket(Account account, IqPacket packet, OnIqPacketReceived callback) { + final XmppConnection connection = account.getXmppConnection(); + if (connection != null) { + connection.sendIqPacket(packet, callback); + } + } + + public static void sendPresencePacket(Account account, PresencePacket packet) { + XmppConnection connection = account.getXmppConnection(); + if (connection != null) { + connection.sendPresencePacket(packet); + } + } +} |