Conversations/src/de/gultsch/chat/services/XmppConnectionService.java

240 lines
8.3 KiB
Java
Raw Normal View History

2014-01-23 20:04:05 -05:00
package de.gultsch.chat.services;
import java.io.IOException;
import java.util.ArrayList;
2014-02-01 09:07:20 -05:00
import java.util.Hashtable;
import java.util.List;
import de.gultsch.chat.entities.Account;
import de.gultsch.chat.entities.Contact;
import de.gultsch.chat.entities.Conversation;
import de.gultsch.chat.entities.Message;
import de.gultsch.chat.persistance.DatabaseBackend;
2014-02-01 09:07:20 -05:00
import de.gultsch.chat.ui.OnConversationListChangedListener;
import de.gultsch.chat.ui.OnRosterFetchedListener;
import de.gultsch.chat.xml.Element;
import de.gultsch.chat.xmpp.IqPacket;
2014-02-01 09:07:20 -05:00
import de.gultsch.chat.xmpp.MessagePacket;
import de.gultsch.chat.xmpp.OnIqPacketReceived;
2014-02-01 09:07:20 -05:00
import de.gultsch.chat.xmpp.OnMessagePacketReceived;
import de.gultsch.chat.xmpp.XmppConnection;
2014-01-23 20:04:05 -05:00
import android.app.Service;
import android.content.Context;
2014-01-23 20:04:05 -05:00
import android.content.Intent;
import android.os.Binder;
import android.os.IBinder;
import android.os.PowerManager;
import android.util.Log;
2014-01-23 20:04:05 -05:00
public class XmppConnectionService extends Service {
protected static final String LOGTAG = "xmppService";
protected DatabaseBackend databaseBackend;
public long startDate;
private List<Account> accounts;
2014-02-01 09:07:20 -05:00
private List<Conversation> conversations = null;
2014-02-01 09:07:20 -05:00
private Hashtable<Account,XmppConnection> connections = new Hashtable<Account, XmppConnection>();
2014-01-23 20:04:05 -05:00
2014-02-01 09:07:20 -05:00
private OnConversationListChangedListener convChangedListener = null;
2014-01-23 20:04:05 -05:00
private final IBinder mBinder = new XmppConnectionBinder();
2014-02-01 09:07:20 -05:00
private OnMessagePacketReceived messageListener = new OnMessagePacketReceived() {
@Override
public void onMessagePacketReceived(Account account, MessagePacket packet) {
2014-02-02 11:53:34 -05:00
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, packet.getBody(), Message.ENCRYPTION_NONE, Message.STATUS_RECIEVED);
conversation.getMessages().add(message);
databaseBackend.createMessage(message);
if (convChangedListener != null) {
convChangedListener.onConversationListChanged();
}
2014-02-01 09:07:20 -05:00
}
}
};
2014-01-23 20:04:05 -05:00
public class XmppConnectionBinder extends Binder {
public XmppConnectionService getService() {
return XmppConnectionService.this;
2014-01-23 20:04:05 -05:00
}
}
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
PowerManager pm = (PowerManager) getSystemService(Context.POWER_SERVICE);
2014-02-01 09:07:20 -05:00
for(Account account : accounts) {
if (!connections.containsKey(account)) {
XmppConnection connection = new XmppConnection(account, pm);
connection.setOnMessagePacketReceivedListener(this.messageListener );
Thread thread = new Thread(connection);
thread.start();
this.connections.put(account, connection);
}
}
return START_STICKY;
}
@Override
public void onCreate() {
databaseBackend = DatabaseBackend.getInstance(getApplicationContext());
this.accounts = databaseBackend.getAccounts();
}
2014-01-23 20:04:05 -05:00
@Override
public IBinder onBind(Intent intent) {
return mBinder;
}
public void sendMessage(final Account account, final Message message) {
new Thread() {
@Override
public void run() {
Log.d(LOGTAG,"sending message for "+account.getJid()+" to: "+message.getCounterpart());
databaseBackend.createMessage(message);
MessagePacket packet = new MessagePacket();
packet.setType(MessagePacket.TYPE_CHAT);
packet.setTo(message.getCounterpart());
packet.setFrom(account.getJid());
packet.setBody(message.getBody());
try {
connections.get(account).sendMessagePacket(packet);
message.setStatus(Message.STATUS_SEND);
databaseBackend.updateMessage(message);
} catch (IOException e) {
Log.d(LOGTAG,"io exception during send. message is in database. will try again later");
}
}
}.start();
}
public void getRoster(final Account account, final OnRosterFetchedListener listener) {
2014-02-02 11:53:34 -05:00
new Thread() {
@Override
public void run() {
IqPacket iqPacket = new IqPacket(IqPacket.TYPE_GET);
Element query = new Element("query");
query.setAttribute("xmlns", "jabber:iq:roster");
query.setAttribute("ver", "");
iqPacket.addChild(query);
try {
connections.get(account).sendIqPacket(iqPacket, new OnIqPacketReceived() {
@Override
public void onIqPacketReceived(Account account, IqPacket packet) {
Element roster = packet.findChild("query");
List<Contact> contacts = new ArrayList<Contact>();
for(Element item : roster.getChildren()) {
String name = item.getAttribute("name");
String jid = item.getAttribute("jid");
if (name==null) {
name = jid.split("@")[0];
}
Contact contact = new Contact(account, name, jid, null);
contacts.add(contact);
}
if (listener != null) {
listener.onRosterFetched(contacts);
}
}
});
} catch (IOException e) {
Log.d(LOGTAG,"io error during roster fetch");
}
}
}.start();
}
public void addConversation(Conversation conversation) {
databaseBackend.createConversation(conversation);
}
2014-02-01 09:07:20 -05:00
public List<Conversation> getConversations() {
if (this.conversations == null) {
Hashtable<String, Account> accountLookupTable = new Hashtable<String, Account>();
for(Account account : this.accounts) {
accountLookupTable.put(account.getUuid(), account);
}
this.conversations = databaseBackend.getConversations(Conversation.STATUS_AVAILABLE);
for(Conversation conv : this.conversations) {
conv.setAccount(accountLookupTable.get(conv.getAccountUuid()));
}
}
return this.conversations;
}
2014-01-28 13:21:54 -05:00
public List<Account> getAccounts() {
return this.accounts;
2014-01-28 13:21:54 -05:00
}
public List<Message> getMessages(Conversation conversation) {
return databaseBackend.getMessages(conversation, 100);
}
2014-01-23 20:04:05 -05:00
public Conversation findOrCreateConversation(Account account, Contact contact) {
2014-02-03 10:04:27 -05:00
//Log.d(LOGTAG,"was asked to find conversation for "+contact.getJid());
2014-02-01 09:07:20 -05:00
for(Conversation conv : this.getConversations()) {
if ((conv.getAccount().equals(account))&&(conv.getContactJid().equals(contact.getJid()))) {
2014-02-03 10:04:27 -05:00
//Log.d(LOGTAG,"found one in memory");
2014-02-01 09:07:20 -05:00
return conv;
}
}
Conversation conversation = databaseBackend.findConversation(account, contact.getJid());
if (conversation!=null) {
Log.d("gultsch","found one. unarchive it");
conversation.setStatus(Conversation.STATUS_AVAILABLE);
2014-02-01 09:07:20 -05:00
conversation.setAccount(account);
this.databaseBackend.updateConversation(conversation);
} else {
2014-02-01 09:07:20 -05:00
Log.d(LOGTAG,"didnt find one in archive. create new one");
conversation = new Conversation(contact.getDisplayName(), contact.getProfilePhoto(), account, contact.getJid());
this.databaseBackend.createConversation(conversation);
}
2014-02-01 09:07:20 -05:00
this.conversations.add(conversation);
if (this.convChangedListener != null) {
this.convChangedListener.onConversationListChanged();
}
return conversation;
}
2014-02-01 09:07:20 -05:00
public void archiveConversation(Conversation conversation) {
this.databaseBackend.updateConversation(conversation);
2014-02-01 09:07:20 -05:00
this.conversations.remove(conversation);
if (this.convChangedListener != null) {
this.convChangedListener.onConversationListChanged();
}
}
public int getConversationCount() {
return this.databaseBackend.getConversationCount();
}
2014-01-28 13:21:54 -05:00
public void createAccount(Account account) {
databaseBackend.createAccount(account);
}
public void updateAccount(Account account) {
databaseBackend.updateAccount(account);
}
public void deleteAccount(Account account) {
databaseBackend.deleteAccount(account);
}
2014-02-01 09:07:20 -05:00
public void setOnConversationListChangedListener(OnConversationListChangedListener listener) {
this.convChangedListener = listener;
}
public void removeOnConversationListChangedListener() {
this.convChangedListener = null;
}
2014-01-23 20:04:05 -05:00
}