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

809 lines
26 KiB
Java
Raw Normal View History

2014-01-23 20:04:05 -05:00
package de.gultsch.chat.services;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
2014-02-01 09:07:20 -05:00
import java.util.Hashtable;
import java.util.List;
2014-02-13 17:40:08 -05:00
import java.util.Set;
import net.java.otr4j.OtrException;
import net.java.otr4j.session.Session;
import net.java.otr4j.session.SessionImpl;
import net.java.otr4j.session.SessionStatus;
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.entities.Presences;
import de.gultsch.chat.persistance.DatabaseBackend;
import de.gultsch.chat.ui.OnAccountListChangedListener;
2014-02-01 09:07:20 -05:00
import de.gultsch.chat.ui.OnConversationListChangedListener;
import de.gultsch.chat.ui.OnRosterFetchedListener;
2014-02-09 21:34:00 -05:00
import de.gultsch.chat.utils.OnPhoneContactsLoadedListener;
import de.gultsch.chat.utils.PhoneHelper;
2014-02-03 12:38:47 -05:00
import de.gultsch.chat.utils.UIHelper;
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;
2014-02-06 20:57:36 -05:00
import de.gultsch.chat.xmpp.OnPresencePacketReceived;
import de.gultsch.chat.xmpp.OnStatusChanged;
import de.gultsch.chat.xmpp.PresencePacket;
import de.gultsch.chat.xmpp.XmppConnection;
2014-02-03 12:38:47 -05:00
import android.app.NotificationManager;
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.database.ContentObserver;
2014-01-23 20:04:05 -05:00
import android.os.Binder;
import android.os.Bundle;
2014-01-23 20:04:05 -05:00
import android.os.IBinder;
import android.os.PowerManager;
import android.provider.ContactsContract;
import android.util.Log;
2014-01-23 20:04:05 -05:00
public class XmppConnectionService extends Service {
2014-02-03 12:38:47 -05:00
protected static final String LOGTAG = "xmppService";
protected DatabaseBackend databaseBackend;
2014-02-03 12:38:47 -05:00
public long startDate;
2014-02-03 12:38:47 -05:00
private List<Account> accounts;
2014-02-01 09:07:20 -05:00
private List<Conversation> conversations = null;
2014-02-03 12:38:47 -05:00
2014-02-01 09:07:20 -05:00
private OnConversationListChangedListener convChangedListener = null;
private OnAccountListChangedListener accountChangedListener = null;
2014-02-11 17:55:03 -05:00
private ContentObserver contactObserver = new ContentObserver(null) {
@Override
2014-02-11 17:55:03 -05:00
public void onChange(boolean selfChange) {
super.onChange(selfChange);
Log.d(LOGTAG, "contact list has changed");
mergePhoneContactsWithRoster();
}
};
2014-02-03 12:38:47 -05:00
private final IBinder mBinder = new XmppConnectionBinder();
2014-02-01 09:07:20 -05:00
private OnMessagePacketReceived messageListener = new OnMessagePacketReceived() {
2014-02-03 12:38:47 -05:00
2014-02-01 09:07:20 -05:00
@Override
2014-02-03 12:38:47 -05:00
public void onMessagePacketReceived(Account account,
MessagePacket packet) {
if ((packet.getType() == MessagePacket.TYPE_CHAT)
|| (packet.getType() == MessagePacket.TYPE_GROUPCHAT)) {
boolean notify = true;
2014-02-13 17:40:08 -05:00
boolean runOtrCheck = false;
2014-02-09 08:10:52 -05:00
int status = Message.STATUS_RECIEVED;
2014-02-13 17:40:08 -05:00
int encryption = Message.ENCRYPTION_NONE;
2014-02-09 08:10:52 -05:00
String body;
String fullJid;
if (!packet.hasChild("body")) {
2014-02-09 08:10:52 -05:00
Element forwarded;
if (packet.hasChild("received")) {
forwarded = packet.findChild("received").findChild(
"forwarded");
} else if (packet.hasChild("sent")) {
forwarded = packet.findChild("sent").findChild(
"forwarded");
status = Message.STATUS_SEND;
2014-02-10 16:45:59 -05:00
notify = false;
2014-02-09 08:10:52 -05:00
} else {
return; // massage has no body and is not carbon. just
2014-02-09 21:34:00 -05:00
// skip
2014-02-09 08:10:52 -05:00
}
if (forwarded != null) {
Element message = forwarded.findChild("message");
if ((message == null) || (!message.hasChild("body")))
return; // either malformed or boring
if (status == Message.STATUS_RECIEVED) {
fullJid = message.getAttribute("from");
} else {
fullJid = message.getAttribute("to");
}
body = message.findChild("body").getContent();
} else {
return; // packet malformed. has no forwarded element
}
} else {
fullJid = packet.getFrom();
body = packet.getBody();
2014-02-13 17:40:08 -05:00
runOtrCheck = true;
}
Conversation conversation = null;
String[] fromParts = fullJid.split("/");
String jid = fromParts[0];
boolean muc = (packet.getType() == MessagePacket.TYPE_GROUPCHAT);
String counterPart = null;
conversation = findOrCreateConversation(account, jid, muc);
if (muc) {
if ((fromParts.length == 1) || (packet.hasChild("subject"))) {
return;
}
counterPart = fromParts[1];
if (counterPart.equals(account.getUsername())) {
status = Message.STATUS_SEND;
notify = false;
}
} else {
counterPart = fullJid;
2014-02-13 17:40:08 -05:00
if ((runOtrCheck) && body.startsWith("?OTR")) {
if (!conversation.hasOtrSession()) {
conversation.startOtrSession(
getApplicationContext(), fromParts[1]);
}
try {
Session otrSession = conversation.getOtrSession();
SessionStatus before = otrSession
.getSessionStatus();
body = otrSession.transformReceiving(body);
SessionStatus after = otrSession.getSessionStatus();
if ((before != after)
&& (after == SessionStatus.ENCRYPTED)) {
Log.d(LOGTAG, "otr session etablished");
List<Message> messages = conversation
.getMessages();
for (int i = 0; i < messages.size(); ++i) {
Message msg = messages.get(i);
if ((msg.getStatus() == Message.STATUS_UNSEND)
&& (msg.getEncryption() == Message.ENCRYPTION_OTR)) {
MessagePacket outPacket = prepareMessagePacket(
account, msg, otrSession);
msg.setStatus(Message.STATUS_SEND);
databaseBackend.updateMessage(msg);
account.getXmppConnection()
.sendMessagePacket(outPacket);
}
}
if (convChangedListener!=null) {
convChangedListener.onConversationListChanged();
}
}
} catch (Exception e) {
Log.d(LOGTAG, "error receiving otr. resetting");
conversation.resetOtrSession();
return;
}
if (body == null) {
return;
}
encryption = Message.ENCRYPTION_OTR;
}
}
2014-02-09 08:10:52 -05:00
Message message = new Message(conversation, counterPart, body,
2014-02-13 17:40:08 -05:00
encryption, status);
if (packet.hasChild("delay")) {
try {
2014-02-11 17:55:03 -05:00
String stamp = packet.findChild("delay").getAttribute(
"stamp");
stamp = stamp.replace("Z", "+0000");
Date date = new SimpleDateFormat(
"yyyy-MM-dd'T'HH:mm:ssZ").parse(stamp);
message.setTime(date.getTime());
} catch (ParseException e) {
2014-02-11 17:55:03 -05:00
Log.d(LOGTAG,
"error trying to parse date" + e.getMessage());
}
}
2014-02-11 17:55:03 -05:00
if (notify) {
2014-02-10 16:45:59 -05:00
message.markUnread();
}
2014-02-02 11:53:34 -05:00
conversation.getMessages().add(message);
databaseBackend.createMessage(message);
if (convChangedListener != null) {
convChangedListener.onConversationListChanged();
2014-02-03 12:38:47 -05:00
} else {
if (notify) {
NotificationManager mNotificationManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
mNotificationManager.notify(2342, UIHelper
.getUnreadMessageNotification(
getApplicationContext(), conversation));
}
2014-02-02 11:53:34 -05:00
}
2014-02-01 09:07:20 -05:00
}
}
};
private OnStatusChanged statusListener = new OnStatusChanged() {
@Override
public void onStatusChanged(Account account) {
if (accountChangedListener != null) {
accountChangedListener.onAccountListChangedListener();
}
if (account.getStatus() == Account.STATUS_ONLINE) {
databaseBackend.clearPresences(account);
connectMultiModeConversations(account);
2014-02-11 17:55:03 -05:00
List<Conversation> conversations = getConversations();
2014-02-13 17:40:08 -05:00
for (int i = 0; i < conversations.size(); ++i) {
if (conversations.get(i).getAccount() == account) {
sendUnsendMessages(conversations.get(i));
}
}
if (convChangedListener != null) {
convChangedListener.onConversationListChanged();
}
}
}
};
2014-02-06 20:57:36 -05:00
private OnPresencePacketReceived presenceListener = new OnPresencePacketReceived() {
2014-02-06 20:57:36 -05:00
@Override
public void onPresencePacketReceived(Account account,
PresencePacket packet) {
String[] fromParts = packet.getAttribute("from").split("/");
Contact contact = findContact(account, fromParts[0]);
if (contact == null) {
2014-02-09 08:10:52 -05:00
// most likely muc, self or roster not synced
// Log.d(LOGTAG,"got presence for non contact "+packet.toString());
return;
}
2014-02-06 20:57:36 -05:00
String type = packet.getAttribute("type");
if (type == null) {
Element show = packet.findChild("show");
2014-02-09 08:10:52 -05:00
if (show == null) {
contact.updatePresence(fromParts[1], Presences.ONLINE);
} else if (show.getContent().equals("away")) {
2014-02-09 08:10:52 -05:00
contact.updatePresence(fromParts[1], Presences.AWAY);
} else if (show.getContent().equals("xa")) {
2014-02-09 08:10:52 -05:00
contact.updatePresence(fromParts[1], Presences.XA);
} else if (show.getContent().equals("chat")) {
2014-02-09 08:10:52 -05:00
contact.updatePresence(fromParts[1], Presences.CHAT);
} else if (show.getContent().equals("dnd")) {
2014-02-09 08:10:52 -05:00
contact.updatePresence(fromParts[1], Presences.DND);
}
databaseBackend.updateContact(contact);
} else if (type.equals("unavailable")) {
2014-02-09 08:10:52 -05:00
if (fromParts.length != 2) {
// Log.d(LOGTAG,"received presence with no resource "+packet.toString());
} else {
contact.removePresence(fromParts[1]);
databaseBackend.updateContact(contact);
}
2014-02-06 20:57:36 -05:00
}
2014-02-13 17:40:08 -05:00
replaceContactInConversation(contact);
2014-02-06 20:57:36 -05:00
}
};
2014-02-13 17:40:08 -05:00
private void replaceContactInConversation(Contact contact) {
List<Conversation> conversations = getConversations();
for(int i = 0; i < conversations.size(); ++i) {
if (conversations.get(i).getContact().equals(contact)) {
conversations.get(i).setContact(contact);
break;
}
}
}
2014-01-23 20:04:05 -05:00
2014-02-03 12:38:47 -05:00
public class XmppConnectionBinder extends Binder {
public XmppConnectionService getService() {
return XmppConnectionService.this;
}
}
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
for (Account account : accounts) {
2014-02-13 17:40:08 -05:00
if (account.getXmppConnection() == null) {
2014-02-04 15:44:16 -05:00
if (!account.isOptionSet(Account.OPTION_DISABLED)) {
2014-02-13 17:40:08 -05:00
account.setXmppConnection(this.createConnection(account));
2014-02-04 15:44:16 -05:00
}
2014-02-03 12:38:47 -05:00
}
}
return START_STICKY;
}
@Override
public void onCreate() {
databaseBackend = DatabaseBackend.getInstance(getApplicationContext());
this.accounts = databaseBackend.getAccounts();
2014-02-11 17:55:03 -05:00
getContentResolver().registerContentObserver(
ContactsContract.Contacts.CONTENT_URI, true, contactObserver);
2014-02-03 12:38:47 -05:00
}
2014-02-13 17:40:08 -05:00
@Override
public void onDestroy() {
super.onDestroy();
for (Account account : accounts) {
if (account.getXmppConnection() != null) {
disconnect(account);
}
}
}
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);
2014-02-06 20:57:36 -05:00
connection.setOnPresencePacketReceivedListener(this.presenceListener);
Thread thread = new Thread(connection);
thread.start();
return connection;
}
2014-02-03 12:38:47 -05:00
2014-02-13 17:40:08 -05:00
private void startOtrSession(Conversation conv) {
Set<String> presences = conv.getContact().getPresences()
.keySet();
if (presences.size() == 0) {
Log.d(LOGTAG, "counter part isnt online. cant use otr");
return;
} else if (presences.size() == 1) {
conv.startOtrSession(getApplicationContext(),
(String) presences.toArray()[0]);
try {
conv.getOtrSession().startSession();
} catch (OtrException e) {
Log.d(LOGTAG, "couldnt actually start");
}
} else {
String latestCounterpartPresence = null;
List<Message> messages = conv.getMessages();
for (int i = messages.size() - 1; i >= 0; --i) {
if (messages.get(i).getStatus() == Message.STATUS_RECIEVED) {
String[] parts = messages.get(i).getCounterpart()
.split("/");
if (parts.length == 2) {
latestCounterpartPresence = parts[1];
break;
}
}
}
if (presences.contains(latestCounterpartPresence)) {
conv.startOtrSession(getApplicationContext(),
latestCounterpartPresence);
try {
conv.getOtrSession().startSession();
} catch (OtrException e) {
// TODO Auto-generated catch block
Log.d(LOGTAG, "couldnt actually start");
}
} else {
Log.d(LOGTAG,
"could not decide where to send otr connection to");
}
}
}
2014-02-11 17:55:03 -05:00
public void sendMessage(Account account, Message message) {
2014-02-13 17:40:08 -05:00
Conversation conv = message.getConversation();
boolean saveInDb = false;
boolean addToConversation = false;
2014-02-11 17:55:03 -05:00
if (account.getStatus() == Account.STATUS_ONLINE) {
2014-02-13 17:40:08 -05:00
MessagePacket packet;
if (message.getEncryption() == Message.ENCRYPTION_OTR) {
if (!conv.hasOtrSession()) {
//starting otr session. messages will be send later
startOtrSession(conv);
} else {
//otr session aleary exists, creating message packet accordingly
packet = prepareMessagePacket(account, message,
conv.getOtrSession());
account.getXmppConnection().sendMessagePacket(packet);
message.setStatus(Message.STATUS_SEND);
}
saveInDb = true;
addToConversation = true;
} else {
// don't encrypt
2014-02-11 17:55:03 -05:00
if (message.getConversation().getMode() == Conversation.MODE_SINGLE) {
2014-02-13 17:40:08 -05:00
message.setStatus(Message.STATUS_SEND);
saveInDb = true;
addToConversation = true;
2014-02-11 17:55:03 -05:00
}
2014-02-13 17:40:08 -05:00
packet = prepareMessagePacket(account, message, null);
account.getXmppConnection().sendMessagePacket(packet);
2014-02-11 17:55:03 -05:00
}
} else {
2014-02-13 17:40:08 -05:00
// account is offline
saveInDb = true;
addToConversation = true;
}
if (saveInDb) {
databaseBackend.createMessage(message);
2014-02-13 17:40:08 -05:00
}
if (addToConversation) {
conv.getMessages().add(message);
if (convChangedListener != null) {
2014-02-11 17:55:03 -05:00
convChangedListener.onConversationListChanged();
}
}
2014-02-13 17:40:08 -05:00
2014-02-11 17:55:03 -05:00
}
private void sendUnsendMessages(Conversation conversation) {
for (int i = 0; i < conversation.getMessages().size(); ++i) {
if (conversation.getMessages().get(i).getStatus() == Message.STATUS_UNSEND) {
2014-02-13 17:40:08 -05:00
Message message = conversation.getMessages().get(i);
2014-02-11 17:55:03 -05:00
MessagePacket packet = prepareMessagePacket(
2014-02-13 17:40:08 -05:00
conversation.getAccount(), message, null);
conversation.getAccount().getXmppConnection()
.sendMessagePacket(packet);
2014-02-11 17:55:03 -05:00
message.setStatus(Message.STATUS_SEND);
if (conversation.getMode() == Conversation.MODE_SINGLE) {
databaseBackend.updateMessage(message);
} else {
databaseBackend.deleteMessage(message);
conversation.getMessages().remove(i);
i--;
}
}
}
2014-02-11 17:55:03 -05:00
}
2014-02-13 17:40:08 -05:00
private MessagePacket prepareMessagePacket(Account account,
Message message, Session otrSession) {
MessagePacket packet = new MessagePacket();
if (message.getConversation().getMode() == Conversation.MODE_SINGLE) {
packet.setType(MessagePacket.TYPE_CHAT);
2014-02-13 17:40:08 -05:00
if (otrSession != null) {
try {
packet.setBody(otrSession.transformSending(message
.getBody()));
} catch (OtrException e) {
Log.d(LOGTAG,
account.getJid()
+ ": could not encrypt message to "
+ message.getCounterpart());
}
Element privateMarker = new Element("private");
privateMarker.setAttribute("xmlns", "urn:xmpp:carbons:2");
packet.addChild(privateMarker);
packet.setTo(otrSession.getSessionID().getAccountID()+"/"+otrSession.getSessionID().getUserID());
packet.setFrom(account.getFullJid());
} else {
packet.setBody(message.getBody());
packet.setTo(message.getCounterpart());
packet.setFrom(account.getJid());
}
} else if (message.getConversation().getMode() == Conversation.MODE_MULTI) {
packet.setType(MessagePacket.TYPE_GROUPCHAT);
2014-02-13 17:40:08 -05:00
packet.setBody(message.getBody());
packet.setTo(message.getCounterpart());
packet.setFrom(account.getJid());
}
2014-02-11 17:55:03 -05:00
return packet;
2014-02-03 12:38:47 -05:00
}
public void getRoster(Account account,
final OnRosterFetchedListener listener) {
2014-02-06 20:57:36 -05:00
List<Contact> contacts = databaseBackend.getContacts(account);
for (int i = 0; i < contacts.size(); ++i) {
contacts.get(i).setAccount(account);
}
if (listener != null) {
listener.onRosterFetched(contacts);
}
}
2014-02-03 12:38:47 -05:00
public void updateRoster(final Account account,
2014-02-03 12:38:47 -05:00
final OnRosterFetchedListener listener) {
2014-02-09 21:34:00 -05:00
PhoneHelper.loadPhoneContacts(this,
new OnPhoneContactsLoadedListener() {
2014-02-09 21:34:00 -05:00
@Override
public void onPhoneContactsLoaded(
final Hashtable<String, Bundle> phoneContacts) {
IqPacket iqPacket = new IqPacket(IqPacket.TYPE_GET);
Element query = new Element("query");
query.setAttribute("xmlns", "jabber:iq:roster");
query.setAttribute("ver", "");
iqPacket.addChild(query);
2014-02-13 17:40:08 -05:00
account.getXmppConnection().sendIqPacket(iqPacket,
2014-02-09 21:34:00 -05:00
new OnIqPacketReceived() {
2014-02-09 21:34:00 -05:00
@Override
public void onIqPacketReceived(
Account account, IqPacket packet) {
List<Contact> contacts = new ArrayList<Contact>();
Element roster = packet
.findChild("query");
if (roster != null) {
for (Element item : roster
.getChildren()) {
Contact contact;
String name = item
.getAttribute("name");
String jid = item
.getAttribute("jid");
if (phoneContacts
.containsKey(jid)) {
Bundle phoneContact = phoneContacts
.get(jid);
String systemAccount = phoneContact
.getInt("phoneid")
+ "#"
+ phoneContact
.getString("lookup");
contact = new Contact(
account,
phoneContact
.getString("displayname"),
jid,
phoneContact
.getString("photouri"));
contact.setSystemAccount(systemAccount);
} else {
if (name == null) {
name = jid.split("@")[0];
}
contact = new Contact(
account, name, jid,
null);
2014-02-09 21:34:00 -05:00
}
contact.setAccount(account);
contact.setSubscription(item
.getAttribute("subscription"));
contacts.add(contact);
}
databaseBackend
.mergeContacts(contacts);
if (listener != null) {
listener.onRosterFetched(contacts);
}
}
}
2014-02-09 21:34:00 -05:00
});
}
});
}
public void mergePhoneContactsWithRoster() {
PhoneHelper.loadPhoneContacts(this,
new OnPhoneContactsLoadedListener() {
@Override
public void onPhoneContactsLoaded(
Hashtable<String, Bundle> phoneContacts) {
List<Contact> contacts = databaseBackend
.getContacts(null);
for (int i = 0; i < contacts.size(); ++i) {
Contact contact = contacts.get(i);
if (phoneContacts.containsKey(contact.getJid())) {
Bundle phoneContact = phoneContacts.get(contact
.getJid());
String systemAccount = phoneContact
.getInt("phoneid")
+ "#"
+ phoneContact.getString("lookup");
contact.setSystemAccount(systemAccount);
contact.setPhotoUri(phoneContact
.getString("photouri"));
contact.setDisplayName(phoneContact
.getString("displayname"));
databaseBackend.updateContact(contact);
} else {
if ((contact.getSystemAccount() != null)
|| (contact.getProfilePhoto() != null)) {
contact.setSystemAccount(null);
contact.setPhotoUri(null);
databaseBackend.updateContact(contact);
}
}
2014-02-09 21:34:00 -05:00
}
}
});
2014-02-03 12:38:47 -05:00
}
public void addConversation(Conversation conversation) {
databaseBackend.createConversation(conversation);
}
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) {
Account account = accountLookupTable.get(conv.getAccountUuid());
conv.setAccount(account);
conv.setContact(findContact(account, conv.getContactJid()));
2014-02-10 16:45:59 -05:00
conv.setMessages(databaseBackend.getMessages(conv, 50));
2014-02-03 12:38:47 -05:00
}
}
return this.conversations;
}
public List<Account> getAccounts() {
return this.accounts;
}
2014-02-11 17:55:03 -05:00
public Contact findContact(Account account, String jid) {
return databaseBackend.findContact(account, jid);
}
2014-02-03 12:38:47 -05:00
2014-02-11 17:55:03 -05:00
public Conversation findOrCreateConversation(Account account, String jid,
boolean muc) {
2014-02-03 12:38:47 -05:00
for (Conversation conv : this.getConversations()) {
if ((conv.getAccount().equals(account))
&& (conv.getContactJid().equals(jid))) {
2014-02-03 12:38:47 -05:00
return conv;
}
}
2014-02-11 17:55:03 -05:00
Conversation conversation = databaseBackend.findConversation(account,
jid);
2014-02-03 12:38:47 -05:00
if (conversation != null) {
conversation.setStatus(Conversation.STATUS_AVAILABLE);
conversation.setAccount(account);
if (muc) {
conversation.setMode(Conversation.MODE_MULTI);
if (account.getStatus() == Account.STATUS_ONLINE) {
2014-02-13 17:40:08 -05:00
joinMuc(conversation);
}
} else {
conversation.setMode(Conversation.MODE_SINGLE);
}
2014-02-03 12:38:47 -05:00
this.databaseBackend.updateConversation(conversation);
} else {
String conversationName;
Contact contact = findContact(account, jid);
2014-02-11 17:55:03 -05:00
if (contact != null) {
conversationName = contact.getDisplayName();
} else {
conversationName = jid.split("@")[0];
}
if (muc) {
2014-02-11 17:55:03 -05:00
conversation = new Conversation(conversationName, account, jid,
Conversation.MODE_MULTI);
if (account.getStatus() == Account.STATUS_ONLINE) {
2014-02-13 17:40:08 -05:00
joinMuc(conversation);
}
} else {
conversation = new Conversation(conversationName, account, jid,
Conversation.MODE_SINGLE);
}
conversation.setContact(contact);
2014-02-03 12:38:47 -05:00
this.databaseBackend.createConversation(conversation);
}
this.conversations.add(conversation);
if (this.convChangedListener != null) {
this.convChangedListener.onConversationListChanged();
}
return conversation;
}
public void archiveConversation(Conversation conversation) {
2014-02-13 17:40:08 -05:00
if (conversation.getMode() == Conversation.MODE_MULTI) {
leaveMuc(conversation);
} else {
try {
conversation.endOtrIfNeeded();
} catch (OtrException e) {
Log.d(LOGTAG,
"error ending otr session for "
+ conversation.getName());
}
}
2014-02-03 12:38:47 -05:00
this.databaseBackend.updateConversation(conversation);
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);
this.accounts.add(account);
2014-02-13 17:40:08 -05:00
account.setXmppConnection(this.createConnection(account));
if (accountChangedListener != null)
accountChangedListener.onAccountListChangedListener();
2014-01-28 13:21:54 -05:00
}
2014-02-03 12:38:47 -05:00
2014-01-28 13:21:54 -05:00
public void updateAccount(Account account) {
databaseBackend.updateAccount(account);
2014-02-13 17:40:08 -05:00
if (account.getXmppConnection() != null) {
disconnect(account);
}
2014-02-04 15:44:16 -05:00
if (!account.isOptionSet(Account.OPTION_DISABLED)) {
2014-02-13 17:40:08 -05:00
account.setXmppConnection(this.createConnection(account));
2014-02-04 15:44:16 -05:00
}
if (accountChangedListener != null)
accountChangedListener.onAccountListChangedListener();
2014-01-28 13:21:54 -05:00
}
public void deleteAccount(Account account) {
Log.d(LOGTAG, "called delete account");
2014-02-13 17:40:08 -05:00
if (account.getXmppConnection() != null) {
this.disconnect(account);
}
2014-01-28 13:21:54 -05:00
databaseBackend.deleteAccount(account);
2014-02-11 17:55:03 -05:00
this.accounts.remove(account);
if (accountChangedListener != null)
accountChangedListener.onAccountListChangedListener();
2014-01-28 13:21:54 -05:00
}
2014-02-03 12:38:47 -05:00
public void setOnConversationListChangedListener(
OnConversationListChangedListener listener) {
2014-02-01 09:07:20 -05:00
this.convChangedListener = listener;
}
2014-02-03 12:38:47 -05:00
2014-02-01 09:07:20 -05:00
public void removeOnConversationListChangedListener() {
this.convChangedListener = null;
}
public void setOnAccountListChangedListener(
OnAccountListChangedListener listener) {
this.accountChangedListener = listener;
}
public void removeOnAccountListChangedListener() {
this.accountChangedListener = null;
}
public void connectMultiModeConversations(Account account) {
List<Conversation> conversations = getConversations();
for (int i = 0; i < conversations.size(); i++) {
Conversation conversation = conversations.get(i);
if ((conversation.getMode() == Conversation.MODE_MULTI)
&& (conversation.getAccount() == account)) {
2014-02-13 17:40:08 -05:00
joinMuc(conversation);
}
}
}
2014-02-13 17:40:08 -05:00
public void joinMuc(Conversation conversation) {
String muc = conversation.getContactJid();
PresencePacket packet = new PresencePacket();
2014-02-13 17:40:08 -05:00
packet.setAttribute("to", muc + "/"
+ conversation.getAccount().getUsername());
Element x = new Element("x");
x.setAttribute("xmlns", "http://jabber.org/protocol/muc");
2014-02-11 17:55:03 -05:00
if (conversation.getMessages().size() != 0) {
Element history = new Element("history");
2014-02-13 17:40:08 -05:00
history.setAttribute("seconds",
2014-02-11 17:55:03 -05:00
(System.currentTimeMillis() - conversation
2014-02-13 17:40:08 -05:00
.getLatestMessage().getTimeSent() / 1000) + "");
x.addChild(history);
}
packet.addChild(x);
2014-02-13 17:40:08 -05:00
conversation.getAccount().getXmppConnection()
.sendPresencePacket(packet);
}
2014-02-13 17:40:08 -05:00
public void leaveMuc(Conversation conversation) {
}
2014-02-13 17:40:08 -05:00
public void disconnect(Account account) {
List<Conversation> conversations = getConversations();
for (int i = 0; i < conversations.size(); i++) {
Conversation conversation = conversations.get(i);
if (conversation.getAccount() == account) {
if (conversation.getMode() == Conversation.MODE_MULTI) {
leaveMuc(conversation);
} else {
try {
conversation.endOtrIfNeeded();
} catch (OtrException e) {
Log.d(LOGTAG, "error ending otr session for "
+ conversation.getName());
}
}
}
}
account.getXmppConnection().disconnect();
Log.d(LOGTAG, "disconnected account: " + account.getJid());
account.setXmppConnection(null);
}
@Override
public IBinder onBind(Intent intent) {
return mBinder;
}
}