aboutsummaryrefslogtreecommitdiffstats
path: root/src/eu/siacs/conversations/services/XmppConnectionService.java
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--src/eu/siacs/conversations/services/XmppConnectionService.java609
1 files changed, 247 insertions, 362 deletions
diff --git a/src/eu/siacs/conversations/services/XmppConnectionService.java b/src/eu/siacs/conversations/services/XmppConnectionService.java
index 3db52753..c43a34b7 100644
--- a/src/eu/siacs/conversations/services/XmppConnectionService.java
+++ b/src/eu/siacs/conversations/services/XmppConnectionService.java
@@ -2,6 +2,7 @@ package eu.siacs.conversations.services;
import java.security.SecureRandom;
import java.text.SimpleDateFormat;
+import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.Date;
@@ -9,6 +10,7 @@ import java.util.Hashtable;
import java.util.List;
import java.util.Locale;
import java.util.TimeZone;
+import java.util.concurrent.CopyOnWriteArrayList;
import org.openintents.openpgp.util.OpenPgpApi;
import org.openintents.openpgp.util.OpenPgpServiceConnection;
@@ -18,6 +20,7 @@ import net.java.otr4j.session.Session;
import net.java.otr4j.session.SessionStatus;
import eu.siacs.conversations.crypto.PgpEngine;
import eu.siacs.conversations.entities.Account;
+import eu.siacs.conversations.entities.Bookmark;
import eu.siacs.conversations.entities.Contact;
import eu.siacs.conversations.entities.Conversation;
import eu.siacs.conversations.entities.Message;
@@ -25,12 +28,12 @@ import eu.siacs.conversations.entities.MucOptions;
import eu.siacs.conversations.entities.MucOptions.OnRenameListener;
import eu.siacs.conversations.entities.Presences;
import eu.siacs.conversations.generator.MessageGenerator;
+import eu.siacs.conversations.generator.PresenceGenerator;
+import eu.siacs.conversations.parser.IqParser;
import eu.siacs.conversations.parser.MessageParser;
import eu.siacs.conversations.parser.PresenceParser;
import eu.siacs.conversations.persistance.DatabaseBackend;
import eu.siacs.conversations.persistance.FileBackend;
-import eu.siacs.conversations.ui.OnAccountListChangedListener;
-import eu.siacs.conversations.ui.OnConversationListChangedListener;
import eu.siacs.conversations.ui.UiCallback;
import eu.siacs.conversations.utils.CryptoHelper;
import eu.siacs.conversations.utils.ExceptionHelper;
@@ -42,8 +45,6 @@ import eu.siacs.conversations.xml.Element;
import eu.siacs.conversations.xmpp.OnBindListener;
import eu.siacs.conversations.xmpp.OnContactStatusChanged;
import eu.siacs.conversations.xmpp.OnIqPacketReceived;
-import eu.siacs.conversations.xmpp.OnMessagePacketReceived;
-import eu.siacs.conversations.xmpp.OnPresencePacketReceived;
import eu.siacs.conversations.xmpp.OnStatusChanged;
import eu.siacs.conversations.xmpp.OnTLSExceptionReceived;
import eu.siacs.conversations.xmpp.XmppConnection;
@@ -86,22 +87,24 @@ public class XmppConnectionService extends Service {
private static final int PING_MIN_INTERVAL = 30;
private static final int PING_TIMEOUT = 10;
private static final int CONNECT_TIMEOUT = 90;
- private static final long CARBON_GRACE_PERIOD = 60000L;
+ public static final long CARBON_GRACE_PERIOD = 60000L;
private static String ACTION_MERGE_PHONE_CONTACTS = "merge_phone_contacts";
private MessageParser mMessageParser = new MessageParser(this);
private PresenceParser mPresenceParser = new PresenceParser(this);
+ private IqParser mIqParser = new IqParser(this);
private MessageGenerator mMessageGenerator = new MessageGenerator();
-
+ private PresenceGenerator mPresenceGenerator = new PresenceGenerator();
+
private List<Account> accounts;
- private List<Conversation> conversations = null;
+ private CopyOnWriteArrayList<Conversation> conversations = null;
private JingleConnectionManager mJingleConnectionManager = new JingleConnectionManager(
this);
- private OnConversationListChangedListener convChangedListener = null;
+ private OnConversationUpdate mOnConversationUpdate = null;
private int convChangedListenerCount = 0;
- private OnAccountListChangedListener accountChangedListener = null;
+ private OnAccountUpdate mOnAccountUpdate = null;
private OnTLSExceptionReceived tlsException = null;
public OnContactStatusChanged onContactStatusChanged = new OnContactStatusChanged() {
@@ -124,8 +127,6 @@ public class XmppConnectionService extends Service {
private SecureRandom mRandom;
- private long lastCarbonMessageReceived = -CARBON_GRACE_PERIOD;
-
private ContentObserver contactObserver = new ContentObserver(null) {
@Override
public void onChange(boolean selfChange) {
@@ -138,101 +139,12 @@ public class XmppConnectionService extends Service {
};
private final IBinder mBinder = new XmppConnectionBinder();
- private OnMessagePacketReceived messageListener = new OnMessagePacketReceived() {
-
- @Override
- public void onMessagePacketReceived(Account account,
- MessagePacket packet) {
- Message message = null;
- boolean notify = true;
- if (getPreferences().getBoolean(
- "notification_grace_period_after_carbon_received", true)) {
- notify = (SystemClock.elapsedRealtime() - lastCarbonMessageReceived) > CARBON_GRACE_PERIOD;
- }
-
- if ((packet.getType() == MessagePacket.TYPE_CHAT)) {
- if ((packet.getBody() != null)
- && (packet.getBody().startsWith("?OTR"))) {
- message = mMessageParser.parseOtrChat(packet, account);
- if (message != null) {
- message.markUnread();
- }
- } else if (packet.hasChild("body")) {
- message = mMessageParser.parseChat(packet, account);
- message.markUnread();
- } else if (packet.hasChild("received")
- || (packet.hasChild("sent"))) {
- message = mMessageParser
- .parseCarbonMessage(packet, account);
- if (message != null) {
- if (message.getStatus() == Message.STATUS_SEND) {
- lastCarbonMessageReceived = SystemClock
- .elapsedRealtime();
- notify = false;
- message.getConversation().markRead();
- } else {
- message.markUnread();
- }
- }
- }
-
- } else if (packet.getType() == MessagePacket.TYPE_GROUPCHAT) {
- message = mMessageParser.parseGroupchat(packet, account);
- if (message != null) {
- if (message.getStatus() == Message.STATUS_RECIEVED) {
- message.markUnread();
- } else {
- message.getConversation().markRead();
- notify = false;
- }
- }
- } else if (packet.getType() == MessagePacket.TYPE_ERROR) {
- mMessageParser.parseError(packet, account);
- return;
- } else if (packet.getType() == MessagePacket.TYPE_NORMAL) {
- mMessageParser.parseNormal(packet, account);
- }
- if ((message == null) || (message.getBody() == null)) {
- return;
- }
- if ((confirmMessages()) && ((packet.getId() != null))) {
- MessagePacket receivedPacket = new MessagePacket();
- receivedPacket.setType(MessagePacket.TYPE_NORMAL);
- receivedPacket.setTo(message.getCounterpart());
- receivedPacket.setFrom(account.getFullJid());
- if (packet.hasChild("markable", "urn:xmpp:chat-markers:0")) {
- Element received = receivedPacket.addChild("received",
- "urn:xmpp:chat-markers:0");
- received.setAttribute("id", packet.getId());
- account.getXmppConnection().sendMessagePacket(
- receivedPacket);
- } else if (packet.hasChild("request", "urn:xmpp:receipts")) {
- Element received = receivedPacket.addChild("received",
- "urn:xmpp:receipts");
- received.setAttribute("id", packet.getId());
- account.getXmppConnection().sendMessagePacket(
- receivedPacket);
- }
- }
- Conversation conversation = message.getConversation();
- conversation.getMessages().add(message);
- if (packet.getType() != MessagePacket.TYPE_ERROR) {
- databaseBackend.createMessage(message);
- }
- if (convChangedListener != null) {
- convChangedListener.onConversationListChanged();
- } else {
- UIHelper.updateNotification(getApplicationContext(),
- getConversations(), message.getConversation(), notify);
- }
- }
- };
private OnStatusChanged statusListener = new OnStatusChanged() {
@Override
public void onStatusChanged(Account account) {
- if (accountChangedListener != null) {
- accountChangedListener.onAccountListChangedListener();
+ if (mOnAccountUpdate != null) {
+ mOnAccountUpdate.onAccountUpdate();;
}
if (account.getStatus() == Account.STATUS_ONLINE) {
mJingleConnectionManager.cancelInTransmission();
@@ -269,73 +181,6 @@ public class XmppConnectionService extends Service {
}
};
- private OnPresencePacketReceived presenceListener = new OnPresencePacketReceived() {
-
- @Override
- public void onPresencePacketReceived(final Account account,
- PresencePacket packet) {
- if (packet.hasChild("x", "http://jabber.org/protocol/muc#user")) {
- mPresenceParser.parseConferencePresence(packet, account);
- } else if (packet.hasChild("x", "http://jabber.org/protocol/muc")) {
- mPresenceParser.parseConferencePresence(packet, account);
- } else {
- mPresenceParser.parseContactPresence(packet, account);
- }
- }
- };
-
- private OnIqPacketReceived unknownIqListener = new OnIqPacketReceived() {
-
- @Override
- public void onIqPacketReceived(Account account, IqPacket packet) {
- if (packet.hasChild("query", "jabber:iq:roster")) {
- String from = packet.getFrom();
- if ((from == null) || (from.equals(account.getJid()))) {
- Element query = packet.findChild("query");
- processRosterItems(account, query);
- } else {
- Log.d(LOGTAG, "unauthorized roster push from: " + from);
- }
- } else if (packet
- .hasChild("open", "http://jabber.org/protocol/ibb")
- || packet
- .hasChild("data", "http://jabber.org/protocol/ibb")) {
- XmppConnectionService.this.mJingleConnectionManager
- .deliverIbbPacket(account, packet);
- } else if (packet.hasChild("query",
- "http://jabber.org/protocol/disco#info")) {
- IqPacket iqResponse = packet
- .generateRespone(IqPacket.TYPE_RESULT);
- Element query = iqResponse.addChild("query",
- "http://jabber.org/protocol/disco#info");
- query.addChild("feature").setAttribute("var",
- "urn:xmpp:jingle:1");
- query.addChild("feature").setAttribute("var",
- "urn:xmpp:jingle:apps:file-transfer:3");
- query.addChild("feature").setAttribute("var",
- "urn:xmpp:jingle:transports:s5b:1");
- query.addChild("feature").setAttribute("var",
- "urn:xmpp:jingle:transports:ibb:1");
- if (confirmMessages()) {
- query.addChild("feature").setAttribute("var",
- "urn:xmpp:receipts");
- }
- account.getXmppConnection().sendIqPacket(iqResponse, null);
- } else {
- if ((packet.getType() == IqPacket.TYPE_GET)
- || (packet.getType() == IqPacket.TYPE_SET)) {
- IqPacket response = packet
- .generateRespone(IqPacket.TYPE_ERROR);
- Element error = response.addChild("error");
- error.setAttribute("type", "cancel");
- error.addChild("feature-not-implemented",
- "urn:ietf:params:xml:ns:xmpp-stanzas");
- account.getXmppConnection().sendIqPacket(response, null);
- }
- }
- }
- };
-
private OnJinglePacketReceived jingleListener = new OnJinglePacketReceived() {
@Override
@@ -401,9 +246,13 @@ public class XmppConnectionService extends Service {
return message;
}
- public Conversation findMuc(String name, Account account) {
+ public Conversation findMuc(Bookmark bookmark) {
+ return findMuc(bookmark.getJid(), bookmark.getAccount());
+ }
+
+ public Conversation findMuc(String jid, Account account) {
for (Conversation conversation : this.conversations) {
- if (conversation.getContactJid().split("/")[0].equals(name)
+ if (conversation.getContactJid().split("/")[0].equals(jid)
&& (conversation.getAccount() == account)) {
return conversation;
}
@@ -411,31 +260,6 @@ public class XmppConnectionService extends Service {
return null;
}
- private void processRosterItems(Account account, Element elements) {
- String version = elements.getAttribute("ver");
- if (version != null) {
- account.getRoster().setVersion(version);
- }
- for (Element item : elements.getChildren()) {
- if (item.getName().equals("item")) {
- String jid = item.getAttribute("jid");
- String name = item.getAttribute("name");
- String subscription = item.getAttribute("subscription");
- Contact contact = account.getRoster().getContact(jid);
- if (!contact.getOption(Contact.Options.DIRTY_PUSH)) {
- contact.setServerName(name);
- }
- if (subscription.equals("remove")) {
- contact.resetOption(Contact.Options.IN_ROSTER);
- contact.resetOption(Contact.Options.DIRTY_DELETE);
- } else {
- contact.setOption(Contact.Options.IN_ROSTER);
- contact.parseSubscriptionFromElement(item);
- }
- }
- }
- }
-
public class XmppConnectionBinder extends Binder {
public XmppConnectionService getService() {
return XmppConnectionService.this;
@@ -508,13 +332,16 @@ public class XmppConnectionService extends Service {
// in any case. reschedule wakup call
this.scheduleWakeupCall(PING_MAX_INTERVAL, true);
}
- if (accountChangedListener != null) {
- accountChangedListener.onAccountListChangedListener();
+ if (mOnAccountUpdate != null) {
+ mOnAccountUpdate.onAccountUpdate();
}
}
}
if (wakeLock.isHeld()) {
- try { wakeLock.release();} catch (RuntimeException re) {}
+ try {
+ wakeLock.release();
+ } catch (RuntimeException re) {
+ }
}
return START_STICKY;
}
@@ -618,11 +445,11 @@ public class XmppConnectionService extends Service {
account.setResource(sharedPref.getString("resource", "mobile")
.toLowerCase(Locale.getDefault()));
XmppConnection connection = new XmppConnection(account, this);
- connection.setOnMessagePacketReceivedListener(this.messageListener);
+ connection.setOnMessagePacketReceivedListener(this.mMessageParser);
connection.setOnStatusChangedListener(this.statusListener);
- connection.setOnPresencePacketReceivedListener(this.presenceListener);
+ connection.setOnPresencePacketReceivedListener(this.mPresenceParser);
connection
- .setOnUnregisteredIqPacketReceivedListener(this.unknownIqListener);
+ .setOnUnregisteredIqPacketReceivedListener(this.mIqParser);
connection.setOnJinglePacketReceivedListener(this.jingleListener);
connection
.setOnTLSExceptionReceivedListener(new OnTLSExceptionReceived() {
@@ -644,11 +471,10 @@ public class XmppConnectionService extends Service {
account.getRoster().clearPresences();
account.clearPresences(); // self presences
fetchRosterFromServer(account);
- sendPresence(account);
+ fetchBookmarks(account);
+ sendPresencePacket(account, mPresenceGenerator.sendPresence(account));
connectMultiModeConversations(account);
- if (convChangedListener != null) {
- convChangedListener.onConversationListChanged();
- }
+ updateConversationUi();
}
});
return connection;
@@ -691,15 +517,12 @@ public class XmppConnectionService extends Service {
message.setStatus(Message.STATUS_WAITING);
} else if (conv.hasValidOtrSession()
&& conv.getOtrSession().getSessionStatus() == SessionStatus.ENCRYPTED) {
- message.setPresence(conv.getOtrSession().getSessionID().getUserID());
- try {
- packet = mMessageGenerator.generateOtrChat(message);
- send = true;
- message.setStatus(Message.STATUS_SEND);
- } catch (OtrException e) {
- Log.e(LOGTAG,"error generating otr packet");
- packet = null;
- }
+ message.setPresence(conv.getOtrSession().getSessionID()
+ .getUserID());
+ packet = mMessageGenerator.generateOtrChat(message);
+ send = true;
+ message.setStatus(Message.STATUS_SEND);
+
} else if (message.getPresence() == null) {
message.setStatus(Message.STATUS_WAITING);
}
@@ -744,11 +567,9 @@ public class XmppConnectionService extends Service {
databaseBackend.createMessage(message);
}
conv.getMessages().add(message);
- if (convChangedListener != null) {
- convChangedListener.onConversationListChanged();
- }
+ updateConversationUi();
if ((send) && (packet != null)) {
- account.getXmppConnection().sendMessagePacket(packet);
+ sendMessagePacket(account, packet);
}
}
@@ -782,9 +603,11 @@ public class XmppConnectionService extends Service {
}
}
} else {
- if (message.getConversation().getOtrSession().getSessionStatus() == SessionStatus.ENCRYPTED) {
+ if (message.getConversation().getOtrSession()
+ .getSessionStatus() == SessionStatus.ENCRYPTED) {
if (message.getType() == Message.TYPE_TEXT) {
- packet = mMessageGenerator.generateOtrChat(message,true);
+ packet = mMessageGenerator.generateOtrChat(message,
+ true);
} else if (message.getType() == Message.TYPE_IMAGE) {
mJingleConnectionManager.createNewConnection(message);
}
@@ -792,9 +615,10 @@ public class XmppConnectionService extends Service {
}
} else if (message.getType() == Message.TYPE_TEXT) {
if (message.getEncryption() == Message.ENCRYPTION_NONE) {
- packet = mMessageGenerator.generateChat(message,true);
- } else if ((message.getEncryption() == Message.ENCRYPTION_DECRYPTED)||(message.getEncryption() == Message.ENCRYPTION_PGP)) {
- packet = mMessageGenerator.generatePgpChat(message,true);
+ packet = mMessageGenerator.generateChat(message, true);
+ } else if ((message.getEncryption() == Message.ENCRYPTION_DECRYPTED)
+ || (message.getEncryption() == Message.ENCRYPTION_PGP)) {
+ packet = mMessageGenerator.generatePgpChat(message, true);
}
} else if (message.getType() == Message.TYPE_IMAGE) {
Presences presences = message.getConversation().getContact()
@@ -813,7 +637,7 @@ public class XmppConnectionService extends Service {
}
}
if (packet != null) {
- account.getXmppConnection().sendMessagePacket(packet);
+ sendMessagePacket(account,packet);
markMessage(message, Message.STATUS_SEND);
}
}
@@ -834,14 +658,60 @@ public class XmppConnectionService extends Service {
@Override
public void onIqPacketReceived(final Account account,
IqPacket packet) {
- Element roster = packet.findChild("query");
- if (roster != null) {
+ Element query = packet.findChild("query");
+ if (query != null) {
account.getRoster().markAllAsNotInRoster();
- processRosterItems(account, roster);
+ mIqParser.rosterItems(account, query);
}
}
});
}
+
+ public void fetchBookmarks(Account account) {
+ IqPacket iqPacket = new IqPacket(IqPacket.TYPE_GET);
+ Element query = iqPacket.query("jabber:iq:private");
+ query.addChild("storage", "storage:bookmarks");
+ OnIqPacketReceived callback = new OnIqPacketReceived() {
+
+ @Override
+ public void onIqPacketReceived(Account account, IqPacket packet) {
+ Element query = packet.query();
+ List<Bookmark> bookmarks = new ArrayList<Bookmark>();
+ Element storage = query.findChild("storage", "storage:bookmarks");
+ if (storage!=null) {
+ for(Element item : storage.getChildren()) {
+ if (item.getName().equals("conference")) {
+ Log.d(LOGTAG,item.toString());
+ Bookmark bookmark = Bookmark.parse(item,account);
+ bookmarks.add(bookmark);
+ Conversation conversation = findMuc(bookmark);
+ if (conversation!=null) {
+ conversation.setBookmark(bookmark);
+ } else {
+ if (bookmark.autojoin()) {
+ conversation = findOrCreateConversation(account, bookmark.getJid(), true);
+ conversation.setBookmark(bookmark);
+ }
+ }
+ }
+ }
+ }
+ account.setBookmarks(bookmarks);
+ }
+ };
+ sendIqPacket(account, iqPacket, callback);
+
+ }
+
+ public void pushBookmarks(Account account) {
+ IqPacket iqPacket = new IqPacket(IqPacket.TYPE_SET);
+ Element query = iqPacket.query("jabber:iq:private");
+ Element storage = query.addChild("storage", "storage:bookmarks");
+ for(Bookmark bookmark : account.getBookmarks()) {
+ storage.addChild(bookmark.toElement());
+ }
+ sendIqPacket(account, iqPacket,null);
+ }
private void mergePhoneContactsWithRoster() {
PhoneHelper.loadPhoneContacts(getApplicationContext(),
@@ -885,7 +755,14 @@ public class XmppConnectionService extends Service {
conv.setMessages(databaseBackend.getMessages(conv, 50));
}
}
- Collections.sort(this.conversations, new Comparator<Conversation>() {
+
+ return this.conversations;
+ }
+
+ public void populateWithOrderedConversations(List<Conversation> list) {
+ list.clear();
+ list.addAll(getConversations());
+ Collections.sort(list, new Comparator<Conversation>() {
@Override
public int compare(Conversation lhs, Conversation rhs) {
Message left = lhs.getLatestMessage();
@@ -899,7 +776,6 @@ public class XmppConnectionService extends Service {
}
}
});
- return this.conversations;
}
public List<Message> getMoreMessages(Conversation conversation,
@@ -968,32 +844,31 @@ public class XmppConnectionService extends Service {
&& (conversation.getMode() == Conversation.MODE_MULTI)) {
joinMuc(conversation);
}
- if (this.convChangedListener != null) {
- this.convChangedListener.onConversationListChanged();
- }
+ updateConversationUi();
return conversation;
}
public void archiveConversation(Conversation conversation) {
if (conversation.getMode() == Conversation.MODE_MULTI) {
+ Bookmark bookmark = conversation.getBookmark();
+ if (bookmark!=null && bookmark.autojoin()) {
+ bookmark.setAutojoin(false);
+ pushBookmarks(bookmark.getAccount());
+ }
leaveMuc(conversation);
} else {
conversation.endOtrIfNeeded();
}
this.databaseBackend.updateConversation(conversation);
this.conversations.remove(conversation);
- if (this.convChangedListener != null) {
- this.convChangedListener.onConversationListChanged();
- }
+ updateConversationUi();
}
public void clearConversationHistory(Conversation conversation) {
this.databaseBackend.deleteMessagesInConversation(conversation);
this.fileBackend.removeFiles(conversation);
conversation.getMessages().clear();
- if (this.convChangedListener != null) {
- this.convChangedListener.onConversationListChanged();
- }
+ updateConversationUi();
}
public int getConversationCount() {
@@ -1004,17 +879,14 @@ public class XmppConnectionService extends Service {
databaseBackend.createAccount(account);
this.accounts.add(account);
this.reconnectAccount(account, false);
- if (accountChangedListener != null)
- accountChangedListener.onAccountListChangedListener();
+ updateAccountUi();
}
public void updateAccount(Account account) {
this.statusListener.onStatusChanged(account);
databaseBackend.updateAccount(account);
reconnectAccount(account, false);
- if (accountChangedListener != null) {
- accountChangedListener.onAccountListChangedListener();
- }
+ updateAccountUi();
UIHelper.showErrorNotification(getApplicationContext(), getAccounts());
}
@@ -1024,32 +896,29 @@ public class XmppConnectionService extends Service {
}
databaseBackend.deleteAccount(account);
this.accounts.remove(account);
- if (accountChangedListener != null) {
- accountChangedListener.onAccountListChangedListener();
- }
+ updateAccountUi();
UIHelper.showErrorNotification(getApplicationContext(), getAccounts());
}
public void setOnConversationListChangedListener(
- OnConversationListChangedListener listener) {
- this.convChangedListener = listener;
+ OnConversationUpdate listener) {
+ this.mOnConversationUpdate = listener;
this.convChangedListenerCount++;
}
public void removeOnConversationListChangedListener() {
this.convChangedListenerCount--;
if (this.convChangedListenerCount == 0) {
- this.convChangedListener = null;
+ this.mOnConversationUpdate = null;
}
}
- public void setOnAccountListChangedListener(
- OnAccountListChangedListener listener) {
- this.accountChangedListener = listener;
+ public void setOnAccountListChangedListener(OnAccountUpdate listener) {
+ this.mOnAccountUpdate = listener;
}
public void removeOnAccountListChangedListener() {
- this.accountChangedListener = null;
+ this.mOnAccountUpdate = null;
}
public void connectMultiModeConversations(Account account) {
@@ -1085,13 +954,16 @@ public class XmppConnectionService extends Service {
packet.addChild("x", "jabber:x:signed").setContent(sig);
}
if (conversation.getMessages().size() != 0) {
- final SimpleDateFormat mDateFormat = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS'Z'",Locale.US);
+ final SimpleDateFormat mDateFormat = new SimpleDateFormat(
+ "yyyy-MM-dd'T'HH:mm:ss.SSS'Z'", Locale.US);
mDateFormat.setTimeZone(TimeZone.getTimeZone("UTC"));
- Date date = new Date(conversation.getLatestMessage().getTimeSent() + 1000);
- x.addChild("history").setAttribute("since",mDateFormat.format(date));
+ Date date = new Date(
+ conversation.getLatestMessage().getTimeSent() + 1000);
+ x.addChild("history").setAttribute("since",
+ mDateFormat.format(date));
}
packet.addChild(x);
- account.getXmppConnection().sendPresencePacket(packet);
+ sendPresencePacket(account, packet);
}
private OnRenameListener renameListener = null;
@@ -1130,8 +1002,7 @@ public class XmppConnectionService extends Service {
packet.addChild("status").setContent("online");
packet.addChild("x", "jabber:x:signed").setContent(sig);
}
-
- account.getXmppConnection().sendPresencePacket(packet, null);
+ sendPresencePacket(account,packet);
} else {
String jid = conversation.getContactJid().split("/")[0] + "/"
+ nick;
@@ -1149,10 +1020,10 @@ public class XmppConnectionService extends Service {
+ "/" + conversation.getMucOptions().getNick());
packet.setAttribute("from", conversation.getAccount().getFullJid());
packet.setAttribute("type", "unavailable");
- Log.d(LOGTAG, "send leaving muc " + packet);
- conversation.getAccount().getXmppConnection()
- .sendPresencePacket(packet);
+ sendPresencePacket(conversation.getAccount(),packet);
conversation.getMucOptions().setOffline();
+ conversation.deregisterWithBookmark();
+ Log.d(LOGTAG,conversation.getAccount().getJid()+" leaving muc "+conversation.getContactJid());
}
public void disconnect(Account account, boolean force) {
@@ -1219,18 +1090,19 @@ public class XmppConnectionService extends Service {
&& (msg.getEncryption() == Message.ENCRYPTION_OTR)) {
msg.setPresence(otrSession.getSessionID().getUserID());
if (msg.getType() == Message.TYPE_TEXT) {
- MessagePacket outPacket = mMessageGenerator.generateOtrChat(msg,true);
- if (outPacket!=null) {
+ MessagePacket outPacket = mMessageGenerator
+ .generateOtrChat(msg, true);
+ if (outPacket != null) {
msg.setStatus(Message.STATUS_SEND);
databaseBackend.updateMessage(msg);
- account.getXmppConnection().sendMessagePacket(outPacket);
+ sendMessagePacket(account,outPacket);
}
} else if (msg.getType() == Message.TYPE_IMAGE) {
mJingleConnectionManager.createNewConnection(msg);
}
}
}
- updateUi(conversation, false);
+ notifyUi(conversation, false);
}
public boolean renewSymmetricKey(Conversation conversation) {
@@ -1250,7 +1122,7 @@ public class XmppConnectionService extends Service {
packet.setBody(otrSession
.transformSending(CryptoHelper.FILETRANSFER
+ CryptoHelper.bytesToHex(symmetricKey)));
- account.getXmppConnection().sendMessagePacket(packet);
+ sendMessagePacket(account,packet);
conversation.setSymmetricKey(symmetricKey);
return true;
} catch (OtrException e) {
@@ -1262,26 +1134,28 @@ public class XmppConnectionService extends Service {
public void pushContactToServer(Contact contact) {
contact.resetOption(Contact.Options.DIRTY_DELETE);
+ contact.setOption(Contact.Options.DIRTY_PUSH);
Account account = contact.getAccount();
if (account.getStatus() == Account.STATUS_ONLINE) {
+ boolean ask = contact.getOption(Contact.Options.ASKING);
+ boolean sendUpdates = contact.getOption(Contact.Options.PENDING_SUBSCRIPTION_REQUEST)
+ && contact.getOption(Contact.Options.PREEMPTIVE_GRANT);
IqPacket iq = new IqPacket(IqPacket.TYPE_SET);
iq.query("jabber:iq:roster").addChild(contact.asElement());
account.getXmppConnection().sendIqPacket(iq, null);
- if (contact.getOption(Contact.Options.ASKING)) {
- requestPresenceUpdatesFrom(contact);
+ if (sendUpdates) {
+ sendPresencePacket(account, mPresenceGenerator.sendPresenceUpdatesTo(contact));
}
- if (contact.getOption(Contact.Options.PENDING_SUBSCRIPTION_REQUEST)) {
- Log.d("xmppService", "contact had pending subscription");
- sendPresenceUpdatesTo(contact);
+ if (ask) {
+ sendPresencePacket(account, mPresenceGenerator.requestPresenceUpdatesFrom(contact));
}
- contact.resetOption(Contact.Options.DIRTY_PUSH);
- } else {
- contact.setOption(Contact.Options.DIRTY_PUSH);
}
}
public void deleteContactOnServer(Contact contact) {
+ contact.resetOption(Contact.Options.PREEMPTIVE_GRANT);
contact.resetOption(Contact.Options.DIRTY_PUSH);
+ contact.setOption(Contact.Options.DIRTY_DELETE);
Account account = contact.getAccount();
if (account.getStatus() == Account.STATUS_ONLINE) {
IqPacket iq = new IqPacket(IqPacket.TYPE_SET);
@@ -1289,53 +1163,7 @@ public class XmppConnectionService extends Service {
item.setAttribute("jid", contact.getJid());
item.setAttribute("subscription", "remove");
account.getXmppConnection().sendIqPacket(iq, null);
- contact.resetOption(Contact.Options.DIRTY_DELETE);
- } else {
- contact.setOption(Contact.Options.DIRTY_DELETE);
- }
- }
-
- public void requestPresenceUpdatesFrom(Contact contact) {
- PresencePacket packet = new PresencePacket();
- packet.setAttribute("type", "subscribe");
- packet.setAttribute("to", contact.getJid());
- packet.setAttribute("from", contact.getAccount().getJid());
- contact.getAccount().getXmppConnection().sendPresencePacket(packet);
- }
-
- public void stopPresenceUpdatesFrom(Contact contact) {
- PresencePacket packet = new PresencePacket();
- packet.setAttribute("type", "unsubscribe");
- packet.setAttribute("to", contact.getJid());
- packet.setAttribute("from", contact.getAccount().getJid());
- contact.getAccount().getXmppConnection().sendPresencePacket(packet);
- }
-
- public void stopPresenceUpdatesTo(Contact contact) {
- PresencePacket packet = new PresencePacket();
- packet.setAttribute("type", "unsubscribed");
- packet.setAttribute("to", contact.getJid());
- packet.setAttribute("from", contact.getAccount().getJid());
- contact.getAccount().getXmppConnection().sendPresencePacket(packet);
- }
-
- public void sendPresenceUpdatesTo(Contact contact) {
- PresencePacket packet = new PresencePacket();
- packet.setAttribute("type", "subscribed");
- packet.setAttribute("to", contact.getJid());
- packet.setAttribute("from", contact.getAccount().getJid());
- contact.getAccount().getXmppConnection().sendPresencePacket(packet);
- }
-
- public void sendPresence(Account account) {
- PresencePacket packet = new PresencePacket();
- packet.setAttribute("from", account.getFullJid());
- String sig = account.getPgpSignature();
- if (sig != null) {
- packet.addChild("status").setContent("online");
- packet.addChild("x", "jabber:x:signed").setContent(sig);
}
- account.getXmppConnection().sendPresencePacket(packet);
}
public void updateConversation(Conversation conversation) {
@@ -1366,21 +1194,6 @@ public class XmppConnectionService extends Service {
}).start();
}
- public void sendConversationSubject(Conversation conversation,
- String subject) {
- MessagePacket packet = new MessagePacket();
- packet.setType(MessagePacket.TYPE_GROUPCHAT);
- packet.setTo(conversation.getContactJid().split("/")[0]);
- Element subjectChild = new Element("subject");
- subjectChild.setContent(subject);
- packet.addChild(subjectChild);
- packet.setFrom(conversation.getAccount().getJid());
- Account account = conversation.getAccount();
- if (account.getStatus() == Account.STATUS_ONLINE) {
- account.getXmppConnection().sendMessagePacket(packet);
- }
- }
-
public void inviteToConference(Conversation conversation,
List<Contact> contacts) {
for (Contact contact : contacts) {
@@ -1394,8 +1207,7 @@ public class XmppConnectionService extends Service {
x.addChild(invite);
packet.addChild(x);
Log.d(LOGTAG, packet.toString());
- conversation.getAccount().getXmppConnection()
- .sendMessagePacket(packet);
+ sendMessagePacket(conversation.getAccount(),packet);
}
}
@@ -1425,9 +1237,7 @@ public class XmppConnectionService extends Service {
public void markMessage(Message message, int status) {
message.setStatus(status);
databaseBackend.updateMessage(message);
- if (convChangedListener != null) {
- convChangedListener.onConversationListChanged();
- }
+ updateConversationUi();
}
public SharedPreferences getPreferences() {
@@ -1439,14 +1249,26 @@ public class XmppConnectionService extends Service {
return getPreferences().getBoolean("confirm_messages", true);
}
- public void updateUi(Conversation conversation, boolean notify) {
- if (convChangedListener != null) {
- convChangedListener.onConversationListChanged();
+ public void notifyUi(Conversation conversation, boolean notify) {
+ if (mOnConversationUpdate != null) {
+ mOnConversationUpdate.onConversationUpdate();
} else {
UIHelper.updateNotification(getApplicationContext(),
getConversations(), conversation, notify);
}
}
+
+ public void updateConversationUi() {
+ if (mOnConversationUpdate != null) {
+ mOnConversationUpdate.onConversationUpdate();
+ }
+ }
+
+ public void updateAccountUi() {
+ if (mOnAccountUpdate != null) {
+ mOnAccountUpdate.onAccountUpdate();
+ }
+ }
public Account findAccountByJid(String accountJid) {
for (Account account : this.accounts) {
@@ -1458,18 +1280,13 @@ public class XmppConnectionService extends Service {
}
public void markRead(Conversation conversation) {
- conversation.markRead(this);
- }
-
- public void sendConfirmMessage(Account account, String to, String id) {
- MessagePacket receivedPacket = new MessagePacket();
- receivedPacket.setType(MessagePacket.TYPE_NORMAL);
- receivedPacket.setTo(to);
- receivedPacket.setFrom(account.getFullJid());
- Element received = receivedPacket.addChild("displayed",
- "urn:xmpp:chat-markers:0");
- received.setAttribute("id", id);
- account.getXmppConnection().sendMessagePacket(receivedPacket);
+ conversation.markRead();
+ String id = conversation.popLatestMarkableMessageId();
+ if (confirmMessages() && id != null) {
+ Account account = conversation.getAccount();
+ String to = conversation.getContactJid();
+ this.sendMessagePacket(conversation.getAccount(), mMessageGenerator.confirm(account, to, id));
+ }
}
public SecureRandom getRNG() {
@@ -1482,19 +1299,87 @@ public class XmppConnectionService extends Service {
public void replyWithNotAcceptable(Account account, MessagePacket packet) {
if (account.getStatus() == Account.STATUS_ONLINE) {
- MessagePacket error = this.mMessageGenerator.generateNotAcceptable(packet);
- account.getXmppConnection().sendMessagePacket(error);
+ MessagePacket error = this.mMessageGenerator
+ .generateNotAcceptable(packet);
+ sendMessagePacket(account,error);
}
}
-
+
public void syncRosterToDisk(final Account account) {
new Thread(new Runnable() {
-
+
@Override
public void run() {
databaseBackend.writeRoster(account.getRoster());
}
}).start();
-
+
+ }
+
+ public List<String> getKnownHosts() {
+ List<String> hosts = new ArrayList<String>();
+ for (Account account : getAccounts()) {
+ if (!hosts.contains(account.getServer())) {
+ hosts.add(account.getServer());
+ }
+ for (Contact contact : account.getRoster().getContacts()) {
+ if (contact.showInRoster()) {
+ String server = contact.getServer();
+ if (server != null && !hosts.contains(server)) {
+ hosts.add(server);
+ }
+ }
+ }
+ }
+ return hosts;
+ }
+
+ public List<String> getKnownConferenceHosts() {
+ ArrayList<String> mucServers = new ArrayList<String>();
+ for (Account account : accounts) {
+ if (account.getXmppConnection() != null) {
+ String server = account.getXmppConnection().getMucServer();
+ if (server != null) {
+ mucServers.add(server);
+ }
+ }
+ }
+ return mucServers;
+ }
+
+ public void sendMessagePacket(Account account, MessagePacket packet) {
+ account.getXmppConnection().sendMessagePacket(packet);
+ }
+
+ public void sendPresencePacket(Account account, PresencePacket packet) {
+ account.getXmppConnection().sendPresencePacket(packet);
+ }
+
+ public void sendIqPacket(Account account, IqPacket packet, OnIqPacketReceived callback) {
+ account.getXmppConnection().sendIqPacket(packet, callback);
+ }
+
+ public MessageGenerator getMessageGenerator() {
+ return this.mMessageGenerator;
+ }
+
+ public PresenceGenerator getPresenceGenerator() {
+ return this.mPresenceGenerator;
+ }
+
+ public JingleConnectionManager getJingleConnectionManager() {
+ return this.mJingleConnectionManager;
+ }
+
+ public interface OnConversationUpdate {
+ public void onConversationUpdate();
+ }
+
+ public interface OnAccountUpdate {
+ public void onAccountUpdate();
+ }
+
+ public interface OnRosterUpdate {
+ public void onRosterUpdate();
}
}