From aa42eb544a1ebf99dc52d71c917b899d1fce628d Mon Sep 17 00:00:00 2001 From: Daniel Gultsch Date: Wed, 5 Feb 2014 22:33:39 +0100 Subject: basic muc support. reworked contact list stuff --- .../chat/services/XmppConnectionService.java | 264 ++++++++++++++++----- 1 file changed, 210 insertions(+), 54 deletions(-) (limited to 'src/de/gultsch/chat/services') diff --git a/src/de/gultsch/chat/services/XmppConnectionService.java b/src/de/gultsch/chat/services/XmppConnectionService.java index ae1140ee..c5477ae0 100644 --- a/src/de/gultsch/chat/services/XmppConnectionService.java +++ b/src/de/gultsch/chat/services/XmppConnectionService.java @@ -19,14 +19,21 @@ import de.gultsch.chat.xmpp.MessagePacket; import de.gultsch.chat.xmpp.OnIqPacketReceived; import de.gultsch.chat.xmpp.OnMessagePacketReceived; import de.gultsch.chat.xmpp.OnStatusChanged; +import de.gultsch.chat.xmpp.PresencePacket; import de.gultsch.chat.xmpp.XmppConnection; import android.app.NotificationManager; import android.app.Service; import android.content.Context; +import android.content.CursorLoader; import android.content.Intent; +import android.content.Loader; +import android.content.Loader.OnLoadCompleteListener; +import android.database.Cursor; import android.os.Binder; +import android.os.Bundle; import android.os.IBinder; import android.os.PowerManager; +import android.provider.ContactsContract; import android.util.Log; public class XmppConnectionService extends Service { @@ -50,15 +57,45 @@ public class XmppConnectionService extends Service { @Override public void onMessagePacketReceived(Account account, MessagePacket packet) { + Conversation conversation = null; + String fullJid = packet.getFrom(); + String counterPart = null; if (packet.getType() == MessagePacket.TYPE_CHAT) { - String fullJid = packet.getFrom(); String jid = fullJid.split("/")[0]; - String name = jid.split("@")[0]; - Contact contact = new Contact(account, name, jid, null); // dummy - // contact - Conversation conversation = findOrCreateConversation(account, - contact); - Message message = new Message(conversation, fullJid, + counterPart = fullJid; + Contact contact = findOrCreateContact(account,jid); + conversation = findOrCreateConversation(account, contact); + } else if (packet.getType() == MessagePacket.TYPE_GROUPCHAT) { + String[] fromParts = fullJid.split("/"); + if (fromParts.length != 2) { + return; + } + if (packet.hasChild("subject")) { + return; + } + if (packet.hasChild("delay")) { + return; + } + + String muc = fromParts[0]; + counterPart = fromParts[1]; + if (counterPart.equals(account.getUsername())) { + return; + } + for (int i = 0; i < conversations.size(); ++i) { + if (conversations.get(i).getContactJid().equals(muc)) { + conversation = conversations.get(i); + break; + } + } + if (conversation == null) { + Log.d(LOGTAG, "couldnt find muc"); + } + + } + if (conversation != null) { + Log.d(LOGTAG, packet.toString()); + Message message = new Message(conversation, counterPart, packet.getBody(), Message.ENCRYPTION_NONE, Message.STATUS_RECIEVED); conversation.getMessages().add(message); @@ -75,13 +112,15 @@ public class XmppConnectionService extends Service { } }; private OnStatusChanged statusListener = new OnStatusChanged() { - + @Override public void onStatusChanged(Account account) { - Log.d(LOGTAG,account.getJid()+" changed status to "+account.getStatus()); if (accountChangedListener != null) { accountChangedListener.onAccountListChangedListener(); } + if (account.getStatus() == Account.STATUS_ONLINE) { + connectMultiModeConversations(account); + } } }; @@ -96,9 +135,11 @@ public class XmppConnectionService extends Service { for (Account account : accounts) { if (!connections.containsKey(account)) { if (!account.isOptionSet(Account.OPTION_DISABLED)) { - this.connections.put(account, this.createConnection(account)); + this.connections.put(account, + this.createConnection(account)); } else { - Log.d(LOGTAG,account.getJid()+": not starting because it's disabled"); + Log.d(LOGTAG, account.getJid() + + ": not starting because it's disabled"); } } } @@ -110,13 +151,12 @@ public class XmppConnectionService extends Service { databaseBackend = DatabaseBackend.getInstance(getApplicationContext()); this.accounts = databaseBackend.getAccounts(); } - + public XmppConnection createConnection(Account account) { PowerManager pm = (PowerManager) getSystemService(Context.POWER_SERVICE); XmppConnection connection = new XmppConnection(account, pm); - connection - .setOnMessagePacketReceivedListener(this.messageListener); - connection.setOnStatusChangedListener(this.statusListener ); + connection.setOnMessagePacketReceivedListener(this.messageListener); + connection.setOnStatusChangedListener(this.statusListener); Thread thread = new Thread(connection); thread.start(); return connection; @@ -132,7 +172,11 @@ public class XmppConnectionService extends Service { + message.getCounterpart()); databaseBackend.createMessage(message); MessagePacket packet = new MessagePacket(); - packet.setType(MessagePacket.TYPE_CHAT); + if (message.getConversation().getMode() == Conversation.MODE_SINGLE) { + packet.setType(MessagePacket.TYPE_CHAT); + } else if (message.getConversation().getMode() == Conversation.MODE_MULTI) { + packet.setType(MessagePacket.TYPE_GROUPCHAT); + } packet.setTo(message.getCounterpart()); packet.setFrom(account.getJid()); packet.setBody(message.getBody()); @@ -140,37 +184,109 @@ public class XmppConnectionService extends Service { message.setStatus(Message.STATUS_SEND); databaseBackend.updateMessage(message); } + + public void getRoster(final OnRosterFetchedListener listener) { + List contacts = databaseBackend.getContacts(); + if (listener != null) { + listener.onRosterFetched(contacts); + } + } - public void getRoster(final Account account, + public void updateRoster(final Account account, final OnRosterFetchedListener listener) { - IqPacket iqPacket = new IqPacket(IqPacket.TYPE_GET); - Element query = new Element("query"); - query.setAttribute("xmlns", "jabber:iq:roster"); - query.setAttribute("ver", ""); - iqPacket.addChild(query); - connections.get(account).sendIqPacket(iqPacket, - new OnIqPacketReceived() { - - @Override - public void onIqPacketReceived(Account account, - IqPacket packet) { - Element roster = packet.findChild("query"); - List contacts = new ArrayList(); - for (Element item : roster.getChildren()) { - String name = item.getAttribute("name"); - String jid = item.getAttribute("jid"); - if (name == null) { - name = jid.split("@")[0]; + + final Hashtable phoneContacts = new Hashtable(); + final List contacts = new ArrayList(); + + final String[] PROJECTION = new String[] { + ContactsContract.Data.CONTACT_ID, + ContactsContract.Data.DISPLAY_NAME, + ContactsContract.Data.PHOTO_THUMBNAIL_URI, + ContactsContract.CommonDataKinds.Im.DATA }; + + final String SELECTION = "(" + ContactsContract.Data.MIMETYPE + "=\"" + + ContactsContract.CommonDataKinds.Im.CONTENT_ITEM_TYPE + + "\") AND (" + ContactsContract.CommonDataKinds.Im.PROTOCOL + + "=\"" + ContactsContract.CommonDataKinds.Im.PROTOCOL_JABBER + + "\")"; + + CursorLoader mCursorLoader = new CursorLoader(this, + ContactsContract.Data.CONTENT_URI, PROJECTION, SELECTION, null, + null); + mCursorLoader.registerListener(0, new OnLoadCompleteListener() { + + @Override + public void onLoadComplete(Loader arg0, Cursor cursor) { + while (cursor.moveToNext()) { + Bundle contact = new Bundle(); + contact.putInt("phoneid", cursor.getInt(cursor + .getColumnIndex(ContactsContract.Data.CONTACT_ID))); + contact.putString( + "displayname", + cursor.getString(cursor + .getColumnIndex(ContactsContract.Data.DISPLAY_NAME))); + contact.putString( + "photouri", + cursor.getString(cursor + .getColumnIndex(ContactsContract.Data.PHOTO_THUMBNAIL_URI))); + phoneContacts.put( + cursor.getString(cursor + .getColumnIndex(ContactsContract.CommonDataKinds.Im.DATA)), + contact); + } + IqPacket iqPacket = new IqPacket(IqPacket.TYPE_GET); + Element query = new Element("query"); + query.setAttribute("xmlns", "jabber:iq:roster"); + query.setAttribute("ver", ""); + iqPacket.addChild(query); + connections.get(account).sendIqPacket(iqPacket, + new OnIqPacketReceived() { + + @Override + public void onIqPacketReceived(Account account, + IqPacket packet) { + Element roster = packet.findChild("query"); + if (roster != null) { + for (Element item : roster.getChildren()) { + Contact contact; + Log.d(LOGTAG, item.toString()); + String name = item.getAttribute("name"); + String jid = item.getAttribute("jid"); + if (phoneContacts.containsKey(jid)) { + Bundle phoneContact = phoneContacts + .get(jid); + contact = new Contact( + account, + phoneContact + .getString("displayname"), + jid, + phoneContact + .getString("photouri")); + contact.setSystemAccount(phoneContact.getInt("phoneid")); + } else { + if (name == null) { + name = jid.split("@")[0]; + } + contact = new Contact(account, + name, jid, null); + + } + contact.setAccount(account); + contact.setSubscription(item + .getAttribute("subscription")); + contacts.add(contact); + } + databaseBackend.mergeContacts(contacts); + if (listener != null) { + listener.onRosterFetched(contacts); + } + } } - Contact contact = new Contact(account, name, jid, - null); - contacts.add(contact); - } - if (listener != null) { - listener.onRosterFetched(contacts); - } - } - }); + }); + + } + }); + mCursorLoader.startLoading(); } public void addConversation(Conversation conversation) { @@ -199,6 +315,15 @@ public class XmppConnectionService extends Service { public List getMessages(Conversation conversation) { return databaseBackend.getMessages(conversation, 100); } + + public Contact findOrCreateContact(Account account, String jid) { + Contact contact = databaseBackend.findContact(account,jid); + if (contact!=null) { + return contact; + } else { + return new Contact(account,jid.split("@")[0], jid, null); + } + } public Conversation findOrCreateConversation(Account account, Contact contact) { @@ -220,7 +345,8 @@ public class XmppConnectionService extends Service { } else { Log.d(LOGTAG, "didnt find one in archive. create new one"); conversation = new Conversation(contact.getDisplayName(), - contact.getProfilePhoto(), account, contact.getJid()); + contact.getProfilePhoto(), account, contact.getJid(), + Conversation.MODE_SINGLE); this.databaseBackend.createConversation(conversation); } this.conversations.add(conversation); @@ -246,7 +372,8 @@ public class XmppConnectionService extends Service { databaseBackend.createAccount(account); this.accounts.add(account); this.connections.put(account, this.createConnection(account)); - if (accountChangedListener!=null) accountChangedListener.onAccountListChangedListener(); + if (accountChangedListener != null) + accountChangedListener.onAccountListChangedListener(); } public void updateAccount(Account account) { @@ -259,21 +386,24 @@ public class XmppConnectionService extends Service { if (!account.isOptionSet(Account.OPTION_DISABLED)) { this.connections.put(account, this.createConnection(account)); } else { - Log.d(LOGTAG,account.getJid()+": not starting because it's disabled"); + Log.d(LOGTAG, account.getJid() + + ": not starting because it's disabled"); } - if (accountChangedListener!=null) accountChangedListener.onAccountListChangedListener(); + if (accountChangedListener != null) + accountChangedListener.onAccountListChangedListener(); } public void deleteAccount(Account account) { - Log.d(LOGTAG,"called delete account"); + Log.d(LOGTAG, "called delete account"); if (this.connections.containsKey(account)) { - Log.d(LOGTAG,"found connection. disconnecting"); + Log.d(LOGTAG, "found connection. disconnecting"); this.connections.get(account).disconnect(); this.connections.remove(account); this.accounts.remove(account); } databaseBackend.deleteAccount(account); - if (accountChangedListener!=null) accountChangedListener.onAccountListChangedListener(); + if (accountChangedListener != null) + accountChangedListener.onAccountListChangedListener(); } public void setOnConversationListChangedListener( @@ -284,12 +414,38 @@ public class XmppConnectionService extends Service { public void removeOnConversationListChangedListener() { this.convChangedListener = null; } - - public void setOnAccountListChangedListener(OnAccountListChangedListener listener) { + + public void setOnAccountListChangedListener( + OnAccountListChangedListener listener) { this.accountChangedListener = listener; } - + public void removeOnAccountListChangedListener() { this.accountChangedListener = null; } + + public void connectMultiModeConversations(Account account) { + List conversations = getConversations(); + for (int i = 0; i < conversations.size(); i++) { + Conversation conversation = conversations.get(i); + if ((conversation.getMode() == Conversation.MODE_MULTI) + && (conversation.getAccount() == account)) { + String muc = conversation.getContactJid(); + Log.d(LOGTAG, + "join muc " + muc + " with account " + account.getJid()); + PresencePacket packet = new PresencePacket(); + packet.setAttribute("to", muc + "/" + account.getUsername()); + Element x = new Element("x"); + x.setAttribute("xmlns", "http://jabber.org/protocol/muc"); + packet.addChild(x); + connections.get(conversation.getAccount()).sendPresencePacket( + packet); + + } + } + } + + public void disconnectMultiModeConversations() { + + } } -- cgit v1.2.3