package org.jivesoftware.smackx.messenger; import java.util.Map; import java.util.UUID; import java.util.concurrent.ConcurrentHashMap; import org.jivesoftware.smack.AbstractConnectionListener; import org.jivesoftware.smack.ReconnectionManager; import org.jivesoftware.smack.SmackException; import org.jivesoftware.smack.XMPPConnection; import org.jivesoftware.smack.XMPPException; import org.jivesoftware.smack.chat2.ChatManager; import org.jivesoftware.smack.roster.Roster; import org.jivesoftware.smackx.caps.EntityCapsManager; import org.jivesoftware.smackx.carbons.CarbonManager; import org.jivesoftware.smackx.csi.ClientStateIndicationManager; import org.jivesoftware.smackx.iqlast.LastActivityManager; import org.jivesoftware.smackx.iqversion.VersionManager; import org.jivesoftware.smackx.messenger.connection.ConnectionFactory; import org.jivesoftware.smackx.messenger.connection.XmppTcpConnectionFactory; import org.jivesoftware.smackx.messenger.csi.ClientStateListener; import org.jivesoftware.smackx.messenger.store.MessengerStore; import org.jivesoftware.smackx.messenger.store.roster.RosterStoreAdapter; import org.jivesoftware.smackx.muc.bookmarkautojoin.MucBookmarkAutojoinManager; import org.jivesoftware.smackx.receipts.DeliveryReceiptManager; import org.jivesoftware.smackx.sid.StableUniqueStanzaIdManager; import org.jivesoftware.smackx.time.EntityTimeManager; import org.jxmpp.stringprep.XmppStringprepException; public class Messenger implements ClientStateListener { private final Map accounts = new ConcurrentHashMap<>(); private final MessengerStore messengerStore; private ConnectionFactory connectionFactory = new XmppTcpConnectionFactory(); public Messenger(MessengerStore store) { this.messengerStore = store; EntityCapsManager.setPersistentCache(store); setGlobalDefaults(); } private void setGlobalDefaults() { ReconnectionManager.setEnabledPerDefault(true); StableUniqueStanzaIdManager.setEnabledByDefault(true); VersionManager.setAutoAppendSmackVersion(false); DeliveryReceiptManager.setDefaultAutoReceiptMode( DeliveryReceiptManager.AutoReceiptMode.ifIsSubscribed); EntityTimeManager.setAutoEnable(true); LastActivityManager.setEnabledPerDefault(true); MucBookmarkAutojoinManager.setAutojoinPerDefault(true); } public XmppAccount addAccount(UUID accountId, String username, String password, String serviceName) throws XmppStringprepException { XMPPConnection connection = connectionFactory.createConnection(username, password, serviceName); XmppAccount xmppAccount = new XmppAccount(accountId, connection); accounts.put(accountId, xmppAccount); offlineAccountSetup(xmppAccount); connection.addConnectionListener(new AbstractConnectionListener() { @Override public void authenticated(XMPPConnection connection, boolean resumed) { if (resumed) { return; } try { onlineAccountSetup(xmppAccount); } catch (InterruptedException | XMPPException | SmackException e) { e.printStackTrace(); } } }); return xmppAccount; } private void offlineAccountSetup(XmppAccount account) { Roster.getInstanceFor(account.getConnection()).setRosterStore( new RosterStoreAdapter(account.getAccountId(), messengerStore)); } private void onlineAccountSetup(XmppAccount account) throws InterruptedException, XMPPException, SmackException { XMPPConnection connection = account.getConnection(); // Enable Carbons CarbonManager carbonManager = CarbonManager.getInstanceFor(connection); if (carbonManager.isSupportedByServer()) { carbonManager.enableCarbons(); } // Disable XHTML-IM ChatManager.getInstanceFor(connection).setXhmtlImEnabled(false); } @Override public synchronized void onClientInForeground() { for (XmppAccount connection : accounts.values()) { trySetCsiActive(connection); } } private void trySetCsiActive(XmppAccount connection) { try { ClientStateIndicationManager.active(connection.getConnection()); } catch (SmackException.NotConnectedException | InterruptedException e) { e.printStackTrace(); } } @Override public synchronized void onClientInBackground() { for (XmppAccount connection : accounts.values()) { trySetCsiInactive(connection); } } private void trySetCsiInactive(XmppAccount connection) { try { ClientStateIndicationManager.inactive(connection.getConnection()); } catch (SmackException.NotConnectedException | InterruptedException e) { e.printStackTrace(); } } }