diff options
Diffstat (limited to 'src/main/java/eu/siacs/conversations/services/XmppConnectionService.java')
-rw-r--r-- | src/main/java/eu/siacs/conversations/services/XmppConnectionService.java | 732 |
1 files changed, 406 insertions, 326 deletions
diff --git a/src/main/java/eu/siacs/conversations/services/XmppConnectionService.java b/src/main/java/eu/siacs/conversations/services/XmppConnectionService.java index ea6f509f..509030c6 100644 --- a/src/main/java/eu/siacs/conversations/services/XmppConnectionService.java +++ b/src/main/java/eu/siacs/conversations/services/XmppConnectionService.java @@ -1,5 +1,40 @@ package eu.siacs.conversations.services; +import android.annotation.SuppressLint; +import android.app.AlarmManager; +import android.app.PendingIntent; +import android.app.Service; +import android.content.Context; +import android.content.Intent; +import android.content.SharedPreferences; +import android.database.ContentObserver; +import android.graphics.Bitmap; +import android.net.ConnectivityManager; +import android.net.NetworkInfo; +import android.net.Uri; +import android.os.Binder; +import android.os.Bundle; +import android.os.FileObserver; +import android.os.IBinder; +import android.os.PowerManager; +import android.os.PowerManager.WakeLock; +import android.os.SystemClock; +import android.preference.PreferenceManager; +import android.provider.ContactsContract; +import android.util.Log; +import android.util.LruCache; + +import net.java.otr4j.OtrException; +import net.java.otr4j.session.Session; +import net.java.otr4j.session.SessionID; +import net.java.otr4j.session.SessionStatus; + +import org.openintents.openpgp.util.OpenPgpApi; +import org.openintents.openpgp.util.OpenPgpServiceConnection; + +import java.io.FileNotFoundException; +import java.io.IOException; +import java.io.OutputStream; import java.security.SecureRandom; import java.text.SimpleDateFormat; import java.util.ArrayList; @@ -12,14 +47,7 @@ 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; - import de.duenndns.ssl.MemorizingTrustManager; - -import net.java.otr4j.OtrException; -import net.java.otr4j.session.Session; -import net.java.otr4j.session.SessionStatus; import eu.siacs.conversations.Config; import eu.siacs.conversations.R; import eu.siacs.conversations.crypto.PgpEngine; @@ -28,6 +56,8 @@ import eu.siacs.conversations.entities.Bookmark; import eu.siacs.conversations.entities.Contact; import eu.siacs.conversations.entities.Conversation; import eu.siacs.conversations.entities.Downloadable; +import eu.siacs.conversations.entities.DownloadableFile; +import eu.siacs.conversations.entities.DownloadablePlaceholder; import eu.siacs.conversations.entities.Message; import eu.siacs.conversations.entities.MucOptions; import eu.siacs.conversations.entities.MucOptions.OnRenameListener; @@ -55,6 +85,8 @@ import eu.siacs.conversations.xmpp.OnIqPacketReceived; import eu.siacs.conversations.xmpp.OnMessageAcknowledged; import eu.siacs.conversations.xmpp.OnStatusChanged; import eu.siacs.conversations.xmpp.XmppConnection; +import eu.siacs.conversations.xmpp.jid.InvalidJidException; +import eu.siacs.conversations.xmpp.jid.Jid; import eu.siacs.conversations.xmpp.jingle.JingleConnectionManager; import eu.siacs.conversations.xmpp.jingle.OnJinglePacketReceived; import eu.siacs.conversations.xmpp.jingle.stanzas.JinglePacket; @@ -62,51 +94,50 @@ import eu.siacs.conversations.xmpp.pep.Avatar; import eu.siacs.conversations.xmpp.stanzas.IqPacket; import eu.siacs.conversations.xmpp.stanzas.MessagePacket; import eu.siacs.conversations.xmpp.stanzas.PresencePacket; -import android.annotation.SuppressLint; -import android.app.AlarmManager; -import android.app.PendingIntent; -import android.app.Service; -import android.content.Context; -import android.content.Intent; -import android.content.SharedPreferences; -import android.database.ContentObserver; -import android.graphics.Bitmap; -import android.net.ConnectivityManager; -import android.net.NetworkInfo; -import android.net.Uri; -import android.os.Binder; -import android.os.Bundle; -import android.os.FileObserver; -import android.os.IBinder; -import android.os.PowerManager; -import android.os.PowerManager.WakeLock; -import android.os.SystemClock; -import android.preference.PreferenceManager; -import android.provider.ContactsContract; -import android.util.Log; -import android.util.LruCache; public class XmppConnectionService extends Service { - public DatabaseBackend databaseBackend; - private FileBackend fileBackend = new FileBackend(this); - - public long startDate; - - private static String ACTION_MERGE_PHONE_CONTACTS = "merge_phone_contacts"; public static String ACTION_CLEAR_NOTIFICATION = "clear_notification"; + private static String ACTION_MERGE_PHONE_CONTACTS = "merge_phone_contacts"; + public static String ACTION_DISABLE_FOREGROUND = "disable_foreground"; + private ContentObserver contactObserver = new ContentObserver(null) { + @Override + public void onChange(boolean selfChange) { + super.onChange(selfChange); + Intent intent = new Intent(getApplicationContext(), + XmppConnectionService.class); + intent.setAction(ACTION_MERGE_PHONE_CONTACTS); + startService(intent); + } + }; + private final IBinder mBinder = new XmppConnectionBinder(); + public DatabaseBackend databaseBackend; + public OnContactStatusChanged onContactStatusChanged = new OnContactStatusChanged() { + @Override + public void onContactStatusChanged(Contact contact, boolean online) { + Conversation conversation = find(getConversations(), contact); + if (conversation != null) { + if (online && contact.getPresences().size() > 1) { + conversation.endOtrIfNeeded(); + } else { + conversation.resetOtrSession(); + } + if (online && (contact.getPresences().size() == 1)) { + sendUnsendMessages(conversation); + } + } + } + }; + private FileBackend fileBackend = new FileBackend(this); private MemorizingTrustManager mMemorizingTrustManager; - private NotificationService mNotificationService = new NotificationService( this); - private MessageParser mMessageParser = new MessageParser(this); private PresenceParser mPresenceParser = new PresenceParser(this); private IqParser mIqParser = new IqParser(this); private MessageGenerator mMessageGenerator = new MessageGenerator(this); private PresenceGenerator mPresenceGenerator = new PresenceGenerator(this); - private List<Account> accounts; private CopyOnWriteArrayList<Conversation> conversations = null; private JingleConnectionManager mJingleConnectionManager = new JingleConnectionManager( @@ -114,56 +145,9 @@ public class XmppConnectionService extends Service { private HttpConnectionManager mHttpConnectionManager = new HttpConnectionManager( this); private AvatarService mAvatarService = new AvatarService(this); - private OnConversationUpdate mOnConversationUpdate = null; private Integer convChangedListenerCount = 0; private OnAccountUpdate mOnAccountUpdate = null; - private Integer accountChangedListenerCount = 0; - private OnRosterUpdate mOnRosterUpdate = null; - private Integer rosterChangedListenerCount = 0; - public OnContactStatusChanged onContactStatusChanged = new OnContactStatusChanged() { - - @Override - public void onContactStatusChanged(Contact contact, boolean online) { - Conversation conversation = find(getConversations(), contact); - if (conversation != null) { - if (online && contact.getPresences().size() > 1) { - conversation.endOtrIfNeeded(); - } else { - conversation.resetOtrSession(); - } - if (online && (contact.getPresences().size() == 1)) { - sendUnsendMessages(conversation); - } - } - } - }; - - private SecureRandom mRandom; - - private ContentObserver contactObserver = new ContentObserver(null) { - @Override - public void onChange(boolean selfChange) { - super.onChange(selfChange); - Intent intent = new Intent(getApplicationContext(), - XmppConnectionService.class); - intent.setAction(ACTION_MERGE_PHONE_CONTACTS); - startService(intent); - } - }; - - private FileObserver fileObserver = new FileObserver( - FileBackend.getConversationsDirectory()) { - - @Override - public void onEvent(int event, String path) { - if (event == FileObserver.DELETE) { - markFileDeleted(path.split("\\.")[0]); - } - } - }; - - private final IBinder mBinder = new XmppConnectionBinder(); private OnStatusChanged statusListener = new OnStatusChanged() { @Override @@ -171,9 +155,8 @@ public class XmppConnectionService extends Service { XmppConnection connection = account.getXmppConnection(); if (mOnAccountUpdate != null) { mOnAccountUpdate.onAccountUpdate(); - ; } - if (account.getStatus() == Account.STATUS_ONLINE) { + if (account.getStatus() == Account.State.ONLINE) { for (Conversation conversation : account.pendingConferenceLeaves) { leaveMuc(conversation); } @@ -182,50 +165,63 @@ public class XmppConnectionService extends Service { } mJingleConnectionManager.cancelInTransmission(); List<Conversation> conversations = getConversations(); - for (int i = 0; i < conversations.size(); ++i) { - if (conversations.get(i).getAccount() == account) { - conversations.get(i).startOtrIfNeeded(); - sendUnsendMessages(conversations.get(i)); + for (Conversation conversation : conversations) { + if (conversation.getAccount() == account) { + conversation.startOtrIfNeeded(); + sendUnsendMessages(conversation); } } if (connection != null && connection.getFeatures().csi()) { if (checkListeners()) { - Log.d(Config.LOGTAG, account.getJid() + Log.d(Config.LOGTAG, account.getJid().toBareJid() + " sending csi//inactive"); connection.sendInactive(); } else { - Log.d(Config.LOGTAG, account.getJid() + Log.d(Config.LOGTAG, account.getJid().toBareJid() + " sending csi//active"); connection.sendActive(); } } syncDirtyContacts(account); scheduleWakeupCall(Config.PING_MAX_INTERVAL, true); - } else if (account.getStatus() == Account.STATUS_OFFLINE) { + } else if (account.getStatus() == Account.State.OFFLINE) { resetSendingToWaiting(account); if (!account.isOptionSet(Account.OPTION_DISABLED)) { int timeToReconnect = mRandom.nextInt(50) + 10; scheduleWakeupCall(timeToReconnect, false); } - } else if (account.getStatus() == Account.STATUS_REGISTRATION_SUCCESSFULL) { + } else if (account.getStatus() == Account.State.REGISTRATION_SUCCESSFUL) { databaseBackend.updateAccount(account); reconnectAccount(account, true); - } else if ((account.getStatus() != Account.STATUS_CONNECTING) - && (account.getStatus() != Account.STATUS_NO_INTERNET)) { + } else if ((account.getStatus() != Account.State.CONNECTING) + && (account.getStatus() != Account.State.NO_INTERNET)) { if (connection != null) { int next = connection.getTimeToNextAttempt(); - Log.d(Config.LOGTAG, account.getJid() + Log.d(Config.LOGTAG, account.getJid().toBareJid() + ": error connecting account. try again in " + next + "s for the " + (connection.getAttempt() + 1) + " time"); scheduleWakeupCall((int) (next * 1.2), false); } - } + } UIHelper.showErrorNotification(getApplicationContext(), getAccounts()); } }; + private Integer accountChangedListenerCount = 0; + private OnRosterUpdate mOnRosterUpdate = null; + private Integer rosterChangedListenerCount = 0; + private SecureRandom mRandom; + private FileObserver fileObserver = new FileObserver( + FileBackend.getConversationsImageDirectory()) { + @Override + public void onEvent(int event, String path) { + if (event == FileObserver.DELETE) { + markFileDeleted(path.split("\\.")[0]); + } + } + }; private OnJinglePacketReceived jingleListener = new OnJinglePacketReceived() { @Override @@ -265,24 +261,26 @@ public class XmppConnectionService extends Service { if (conversation.getAccount() == account) { for (Message message : conversation.getMessages()) { if ((message.getStatus() == Message.STATUS_UNSEND || message - .getStatus() == Message.STATUS_WAITING) + .getStatus() == Message.STATUS_WAITING) && message.getUuid().equals(uuid)) { markMessage(message, Message.STATUS_SEND); return; - } + } } } } } }; private LruCache<String, Bitmap> mBitmapCache; + private OnRenameListener renameListener = null; + private IqGenerator mIqGenerator = new IqGenerator(this); public PgpEngine getPgpEngine() { if (pgpServiceConnection.isBound()) { if (this.mPgpEngine == null) { this.mPgpEngine = new PgpEngine(new OpenPgpApi( - getApplicationContext(), - pgpServiceConnection.getService()), this); + getApplicationContext(), + pgpServiceConnection.getService()), this); } return mPgpEngine; } else { @@ -299,7 +297,49 @@ public class XmppConnectionService extends Service { return this.mAvatarService; } - public Message attachImageToConversation(final Conversation conversation, + public void attachFileToConversation(Conversation conversation, final Uri uri, final UiCallback<Message> callback) { + final Message message; + if (conversation.getNextEncryption(forceEncryption()) == Message.ENCRYPTION_PGP) { + message = new Message(conversation, "", + Message.ENCRYPTION_DECRYPTED); + } else { + message = new Message(conversation, "", + conversation.getNextEncryption(forceEncryption())); + } + message.setCounterpart(conversation.getNextCounterpart()); + message.setType(Message.TYPE_FILE); + message.setStatus(Message.STATUS_OFFERED); + String path = getFileBackend().getOriginalPath(uri); + if (path!=null) { + message.setRelativeFilePath(path); + getFileBackend().updateFileParams(message); + if (message.getEncryption() == Message.ENCRYPTION_DECRYPTED) { + getPgpEngine().encrypt(message, callback); + } else { + callback.success(message); + } + } else { + new Thread(new Runnable() { + @Override + public void run() { + try { + getFileBackend().copyFileToPrivateStorage(message, uri); + getFileBackend().updateFileParams(message); + if (message.getEncryption() == Message.ENCRYPTION_DECRYPTED) { + getPgpEngine().encrypt(message, callback); + } else { + callback.success(message); + } + } catch (FileBackend.FileCopyException e) { + callback.error(e.getResId(),message); + } + } + }).start(); + + } + } + + public void attachImageToConversation(final Conversation conversation, final Uri uri, final UiCallback<Message> callback) { final Message message; if (conversation.getNextEncryption(forceEncryption()) == Message.ENCRYPTION_PGP) { @@ -309,7 +349,7 @@ public class XmppConnectionService extends Service { message = new Message(conversation, "", conversation.getNextEncryption(forceEncryption())); } - message.setPresence(conversation.getNextPresence()); + message.setCounterpart(conversation.getNextCounterpart()); message.setType(Message.TYPE_IMAGE); message.setStatus(Message.STATUS_OFFERED); new Thread(new Runnable() { @@ -317,34 +357,27 @@ public class XmppConnectionService extends Service { @Override public void run() { try { - getFileBackend().copyImageToPrivateStorage(message, uri); + DownloadableFile file = getFileBackend().copyImageToPrivateStorage(message, uri); if (conversation.getNextEncryption(forceEncryption()) == Message.ENCRYPTION_PGP) { getPgpEngine().encrypt(message, callback); } else { callback.success(message); } - } catch (FileBackend.ImageCopyException e) { + } catch (FileBackend.FileCopyException e) { callback.error(e.getResId(), message); } } }).start(); - return message; } public Conversation find(Bookmark bookmark) { return find(bookmark.getAccount(), bookmark.getJid()); } - public Conversation find(Account account, String jid) { + public Conversation find(final Account account, final Jid jid) { return find(getConversations(), account, jid); } - public class XmppConnectionBinder extends Binder { - public XmppConnectionService getService() { - return XmppConnectionService.this; - } - } - @Override public int onStartCommand(Intent intent, int flags, int startId) { if (intent != null && intent.getAction() != null) { @@ -356,6 +389,9 @@ public class XmppConnectionService extends Service { return START_NOT_STICKY; } else if (intent.getAction().equals(ACTION_CLEAR_NOTIFICATION)) { mNotificationService.clear(); + } else if (intent.getAction().equals(ACTION_DISABLE_FOREGROUND)) { + getPreferences().edit().putBoolean("keep_foreground_service",false).commit(); + toggleForegroundService(); } } this.wakeLock.acquire(); @@ -363,22 +399,22 @@ public class XmppConnectionService extends Service { for (Account account : accounts) { if (!account.isOptionSet(Account.OPTION_DISABLED)) { if (!hasInternetConnection()) { - account.setStatus(Account.STATUS_NO_INTERNET); + account.setStatus(Account.State.NO_INTERNET); if (statusListener != null) { statusListener.onStatusChanged(account); } } else { - if (account.getStatus() == Account.STATUS_NO_INTERNET) { - account.setStatus(Account.STATUS_OFFLINE); + if (account.getStatus() == Account.State.NO_INTERNET) { + account.setStatus(Account.State.OFFLINE); if (statusListener != null) { statusListener.onStatusChanged(account); } } - if (account.getStatus() == Account.STATUS_ONLINE) { + if (account.getStatus() == Account.State.ONLINE) { long lastReceived = account.getXmppConnection() - .getLastPacketReceived(); + .getLastPacketReceived(); long lastSent = account.getXmppConnection() - .getLastPingSent(); + .getLastPingSent(); if (lastSent - lastReceived >= Config.PING_TIMEOUT * 1000) { Log.d(Config.LOGTAG, account.getJid() + ": ping timeout"); @@ -387,13 +423,13 @@ public class XmppConnectionService extends Service { account.getXmppConnection().sendPing(); this.scheduleWakeupCall(2, false); } - } else if (account.getStatus() == Account.STATUS_OFFLINE) { + } else if (account.getStatus() == Account.State.OFFLINE) { if (account.getXmppConnection() == null) { account.setXmppConnection(this .createConnection(account)); } new Thread(account.getXmppConnection()).start(); - } else if ((account.getStatus() == Account.STATUS_CONNECTING) + } else if ((account.getStatus() == Account.State.CONNECTING) && ((SystemClock.elapsedRealtime() - account .getXmppConnection().getLastConnect()) / 1000 >= Config.CONNECT_TIMEOUT)) { Log.d(Config.LOGTAG, account.getJid() @@ -412,10 +448,14 @@ public class XmppConnectionService extends Service { } } } + /*PowerManager pm = (PowerManager) this.getSystemService(Context.POWER_SERVICE); + if (!pm.isScreenOn()) { + removeStaleListeners(); + }*/ if (wakeLock.isHeld()) { try { wakeLock.release(); - } catch (RuntimeException re) { + } catch (final RuntimeException ignored) { } } return START_STICKY; @@ -423,7 +463,7 @@ public class XmppConnectionService extends Service { public boolean hasInternetConnection() { ConnectivityManager cm = (ConnectivityManager) getApplicationContext() - .getSystemService(Context.CONNECTIVITY_SERVICE); + .getSystemService(Context.CONNECTIVITY_SERVICE); NetworkInfo activeNetwork = cm.getActiveNetworkInfo(); return activeNetwork != null && activeNetwork.isConnected(); } @@ -447,10 +487,11 @@ public class XmppConnectionService extends Service { }; this.databaseBackend = DatabaseBackend - .getInstance(getApplicationContext()); + .getInstance(getApplicationContext()); this.accounts = databaseBackend.getAccounts(); for (Account account : this.accounts) { + account.initOtrEngine(this); this.databaseBackend.readRoster(account.getRoster()); } this.mergePhoneContactsWithRoster(); @@ -466,18 +507,23 @@ public class XmppConnectionService extends Service { this.pm = (PowerManager) getSystemService(Context.POWER_SERVICE); this.wakeLock = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "XmppConnectionService"); + toggleForegroundService(); } - @Override - public void onDestroy() { - super.onDestroy(); - this.logoutAndSave(); + public void toggleForegroundService() { + if (getPreferences().getBoolean("keep_foreground_service",false)) { + startForeground(NotificationService.FOREGROUND_NOTIFICATION_ID, this.mNotificationService.createForegroundNotification()); + } else { + stopForeground(true); + } } @Override public void onTaskRemoved(Intent rootIntent) { super.onTaskRemoved(rootIntent); - this.logoutAndSave(); + if (!getPreferences().getBoolean("keep_foreground_service",false)) { + this.logoutAndSave(); + } } private void logoutAndSave() { @@ -489,7 +535,7 @@ public class XmppConnectionService extends Service { } Context context = getApplicationContext(); AlarmManager alarmManager = (AlarmManager) context - .getSystemService(Context.ALARM_SERVICE); + .getSystemService(Context.ALARM_SERVICE); Intent intent = new Intent(context, EventReceiver.class); alarmManager.cancel(PendingIntent.getBroadcast(context, 0, intent, 0)); Log.d(Config.LOGTAG, "good bye"); @@ -500,7 +546,7 @@ public class XmppConnectionService extends Service { long timeToWake = SystemClock.elapsedRealtime() + seconds * 1000; Context context = getApplicationContext(); AlarmManager alarmManager = (AlarmManager) context - .getSystemService(Context.ALARM_SERVICE); + .getSystemService(Context.ALARM_SERVICE); if (ping) { if (this.pingIntent == null) { @@ -521,7 +567,7 @@ public class XmppConnectionService extends Service { context, 0, this.pingIntent, 0); alarmManager.set(AlarmManager.ELAPSED_REALTIME_WAKEUP, timeToWake, pendingPingIntent); - } + } } } else { Intent intent = new Intent(context, EventReceiver.class); @@ -546,7 +592,7 @@ public class XmppConnectionService extends Service { connection.setOnJinglePacketReceivedListener(this.jingleListener); connection.setOnBindListener(this.mOnBindListener); connection - .setOnMessageAcknowledgeListener(this.mOnMessageAcknowledgedListener); + .setOnMessageAcknowledgeListener(this.mOnMessageAcknowledgedListener); return connection; } @@ -557,21 +603,19 @@ public class XmppConnectionService extends Service { MessagePacket packet = null; boolean saveInDb = true; boolean send = false; - if (account.getStatus() == Account.STATUS_ONLINE + if (account.getStatus() == Account.State.ONLINE && account.getXmppConnection() != null) { - if (message.getType() == Message.TYPE_IMAGE) { - if (message.getPresence() != null) { + if (message.getType() == Message.TYPE_IMAGE || message.getType() == Message.TYPE_FILE) { + if (message.getCounterpart() != null) { if (message.getEncryption() == Message.ENCRYPTION_OTR) { - if (!conv.hasValidOtrSession() - && (message.getPresence() != null)) { - conv.startOtrSession(this, message.getPresence(), - true); + if (!conv.hasValidOtrSession()) { + conv.startOtrSession(message.getCounterpart().getResourcepart(),true); message.setStatus(Message.STATUS_WAITING); } else if (conv.hasValidOtrSession() && conv.getOtrSession().getSessionStatus() == SessionStatus.ENCRYPTED) { mJingleConnectionManager - .createNewConnection(message); - } + .createNewConnection(message); + } } else { mJingleConnectionManager.createNewConnection(message); } @@ -583,19 +627,18 @@ public class XmppConnectionService extends Service { } } else { if (message.getEncryption() == Message.ENCRYPTION_OTR) { - if (!conv.hasValidOtrSession() - && (message.getPresence() != null)) { - conv.startOtrSession(this, message.getPresence(), true); + if (!conv.hasValidOtrSession() && (message.getCounterpart() != null)) { + conv.startOtrSession(message.getCounterpart().getResourcepart(), true); message.setStatus(Message.STATUS_WAITING); - } else if (conv.hasValidOtrSession() - && conv.getOtrSession().getSessionStatus() == SessionStatus.ENCRYPTED) { - message.setPresence(conv.getOtrSession().getSessionID() - .getUserID()); - packet = mMessageGenerator.generateOtrChat(message); - send = true; - - } else if (message.getPresence() == null) { - conv.startOtrIfNeeded(); + } else if (conv.hasValidOtrSession()) { + if (conv.getOtrSession().getSessionStatus() == SessionStatus.ENCRYPTED) { + packet = mMessageGenerator.generateOtrChat(message); + send = true; + } else { + message.setStatus(Message.STATUS_WAITING); + conv.startOtrIfNeeded(); + } + } else { message.setStatus(Message.STATUS_WAITING); } } else if (message.getEncryption() == Message.ENCRYPTION_DECRYPTED) { @@ -613,7 +656,7 @@ public class XmppConnectionService extends Service { if (!account.getXmppConnection().getFeatures().sm() && conv.getMode() != Conversation.MODE_MULTI) { message.setStatus(Message.STATUS_SEND); - } + } } else { message.setStatus(Message.STATUS_WAITING); if (message.getType() == Message.TYPE_TEXT) { @@ -627,13 +670,10 @@ public class XmppConnectionService extends Service { message.setBody(decryptedBody); message.setEncryption(Message.ENCRYPTION_DECRYPTED); } else if (message.getEncryption() == Message.ENCRYPTION_OTR) { - if (conv.hasValidOtrSession()) { - message.setPresence(conv.getOtrSession().getSessionID() - .getUserID()); - } else if (!conv.hasValidOtrSession() - && message.getPresence() != null) { - conv.startOtrSession(this, message.getPresence(), false); - } + if (!conv.hasValidOtrSession() + && message.getCounterpart() != null) { + conv.startOtrSession(message.getCounterpart().getResourcepart(), false); + } } } @@ -643,7 +683,7 @@ public class XmppConnectionService extends Service { if (message.getEncryption() == Message.ENCRYPTION_NONE || saveEncryptedMessages()) { databaseBackend.createMessage(message); - } + } } if ((send) && (packet != null)) { sendMessagePacket(account, packet); @@ -665,29 +705,32 @@ public class XmppConnectionService extends Service { MessagePacket packet = null; if (message.getEncryption() == Message.ENCRYPTION_OTR) { Presences presences = message.getConversation().getContact() - .getPresences(); + .getPresences(); if (!message.getConversation().hasValidOtrSession()) { - if ((message.getPresence() != null) - && (presences.has(message.getPresence()))) { - message.getConversation().startOtrSession(this, - message.getPresence(), true); + if ((message.getCounterpart() != null) + && (presences.has(message.getCounterpart().getResourcepart()))) { + message.getConversation().startOtrSession(message.getCounterpart().getResourcepart(), true); } else { if (presences.size() == 1) { String presence = presences.asStringArray()[0]; - message.getConversation().startOtrSession(this, - presence, true); + message.getConversation().startOtrSession(presence, true); } } } else { if (message.getConversation().getOtrSession() .getSessionStatus() == SessionStatus.ENCRYPTED) { - if (message.getType() == Message.TYPE_TEXT) { - packet = mMessageGenerator.generateOtrChat(message, - true); - } else if (message.getType() == Message.TYPE_IMAGE) { - mJingleConnectionManager.createNewConnection(message); + try { + message.setCounterpart(Jid.fromSessionID(message.getConversation().getOtrSession().getSessionID())); + if (message.getType() == Message.TYPE_TEXT) { + packet = mMessageGenerator.generateOtrChat(message, + true); + } else if (message.getType() == Message.TYPE_IMAGE || message.getType() == Message.TYPE_FILE) { + mJingleConnectionManager.createNewConnection(message); + } + } catch (InvalidJidException e) { + } - } + } } } else if (message.getType() == Message.TYPE_TEXT) { if (message.getEncryption() == Message.ENCRYPTION_NONE) { @@ -695,18 +738,22 @@ public class XmppConnectionService extends Service { } 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() - .getPresences(); - if ((message.getPresence() != null) - && (presences.has(message.getPresence()))) { + } + } else if (message.getType() == Message.TYPE_IMAGE || message.getType() == Message.TYPE_FILE) { + Contact contact = message.getConversation().getContact(); + Presences presences = contact.getPresences(); + if ((message.getCounterpart() != null) + && (presences.has(message.getCounterpart().getResourcepart()))) { markMessage(message, Message.STATUS_OFFERED); mJingleConnectionManager.createNewConnection(message); } else { if (presences.size() == 1) { String presence = presences.asStringArray()[0]; - message.setPresence(presence); + try { + message.setCounterpart(Jid.fromParts(contact.getJid().getLocalpart(), contact.getJid().getDomainpart(), presence)); + } catch (InvalidJidException e) { + return; + } markMessage(message, Message.STATUS_OFFERED); mJingleConnectionManager.createNewConnection(message); } @@ -726,10 +773,10 @@ public class XmppConnectionService extends Service { public void fetchRosterFromServer(Account account) { IqPacket iqPacket = new IqPacket(IqPacket.TYPE_GET); if (!"".equals(account.getRosterVersion())) { - Log.d(Config.LOGTAG, account.getJid() + Log.d(Config.LOGTAG, account.getJid().toBareJid() + ": fetching roster version " + account.getRosterVersion()); } else { - Log.d(Config.LOGTAG, account.getJid() + ": fetching roster"); + Log.d(Config.LOGTAG, account.getJid().toBareJid() + ": fetching roster"); } iqPacket.query("jabber:iq:roster").setAttribute("ver", account.getRosterVersion()); @@ -757,7 +804,7 @@ public class XmppConnectionService extends Service { @Override public void onIqPacketReceived(Account account, IqPacket packet) { Element query = packet.query(); - List<Bookmark> bookmarks = new CopyOnWriteArrayList<Bookmark>(); + List<Bookmark> bookmarks = new CopyOnWriteArrayList<>(); Element storage = query.findChild("storage", "storage:bookmarks"); if (storage != null) { @@ -806,13 +853,19 @@ public class XmppConnectionService extends Service { } for (Bundle phoneContact : phoneContacts) { for (Account account : accounts) { - String jid = phoneContact.getString("jid"); - Contact contact = account.getRoster() - .getContact(jid); + Jid jid; + try { + jid = Jid.fromString(phoneContact.getString("jid")); + } catch (final InvalidJidException e) { + // TODO: Warn if contact import fails here? + break; + } + final Contact contact = account.getRoster() + .getContact(jid); String systemAccount = phoneContact - .getInt("phoneid") - + "#" - + phoneContact.getString("lookup"); + .getInt("phoneid") + + "#" + + phoneContact.getString("lookup"); contact.setSystemAccount(systemAccount); contact.setPhotoUri(phoneContact .getString("photouri")); @@ -827,12 +880,12 @@ public class XmppConnectionService extends Service { public List<Conversation> getConversations() { if (this.conversations == null) { - Hashtable<String, Account> accountLookupTable = new Hashtable<String, Account>(); + Hashtable<String, Account> accountLookupTable = new Hashtable<>(); for (Account account : this.accounts) { accountLookupTable.put(account.getUuid(), account); } this.conversations = databaseBackend - .getConversations(Conversation.STATUS_AVAILABLE); + .getConversations(Conversation.STATUS_AVAILABLE); for (Conversation conv : this.conversations) { Account account = accountLookupTable.get(conv.getAccountUuid()); conv.setAccount(account); @@ -845,12 +898,12 @@ public class XmppConnectionService extends Service { private void checkDeletedFiles(Conversation conversation) { for (Message message : conversation.getMessages()) { - if (message.getType() == Message.TYPE_IMAGE + if ((message.getType() == Message.TYPE_IMAGE || message.getType() == Message.TYPE_FILE) && message.getEncryption() != Message.ENCRYPTION_PGP) { if (!getFileBackend().isFileAvailable(message)) { - message.setDownloadable(new DeletedDownloadable()); + message.setDownloadable(new DownloadablePlaceholder(Downloadable.STATUS_DELETED)); } - } + } } } @@ -861,11 +914,11 @@ public class XmppConnectionService extends Service { && message.getEncryption() != Message.ENCRYPTION_PGP && message.getUuid().equals(uuid)) { if (!getFileBackend().isFileAvailable(message)) { - message.setDownloadable(new DeletedDownloadable()); + message.setDownloadable(new DownloadablePlaceholder(Downloadable.STATUS_DELETED)); updateConversationUi(); } return; - } + } } } } @@ -925,20 +978,20 @@ public class XmppConnectionService extends Service { return null; } - public Conversation find(List<Conversation> haystack, Account account, - String jid) { + public Conversation find(final List<Conversation> haystack, + final Account account, + final Jid jid) { for (Conversation conversation : haystack) { if ((account == null || conversation.getAccount() == account) - && (conversation.getContactJid().split("/", 2)[0] - .equalsIgnoreCase(jid))) { + && (conversation.getContactJid().toBareJid().equals(jid.toBareJid()))) { return conversation; - } + } } return null; } - public Conversation findOrCreateConversation(Account account, String jid, - boolean muc) { + public Conversation findOrCreateConversation(final Account account, final Jid jid, + final boolean muc) { Conversation conversation = find(account, jid); if (conversation != null) { return conversation; @@ -953,7 +1006,7 @@ public class XmppConnectionService extends Service { conversation.setMode(Conversation.MODE_SINGLE); } conversation.setMessages(databaseBackend.getMessages(conversation, - 50)); + 50)); this.databaseBackend.updateConversation(conversation); } else { String conversationName; @@ -961,7 +1014,7 @@ public class XmppConnectionService extends Service { if (contact != null) { conversationName = contact.getDisplayName(); } else { - conversationName = jid.split("@")[0]; + conversationName = jid.getLocalpart(); } if (muc) { conversation = new Conversation(conversationName, account, jid, @@ -979,7 +1032,7 @@ public class XmppConnectionService extends Service { public void archiveConversation(Conversation conversation) { if (conversation.getMode() == Conversation.MODE_MULTI) { - if (conversation.getAccount().getStatus() == Account.STATUS_ONLINE) { + if (conversation.getAccount().getStatus() == Account.State.ONLINE) { Bookmark bookmark = conversation.getBookmark(); if (bookmark != null && bookmark.autojoin()) { bookmark.setAutojoin(false); @@ -1006,6 +1059,7 @@ public class XmppConnectionService extends Service { } public void createAccount(Account account) { + account.initOtrEngine(this); databaseBackend.createAccount(account); this.accounts.add(account); this.reconnectAccount(account, false); @@ -1040,13 +1094,53 @@ public class XmppConnectionService extends Service { UIHelper.showErrorNotification(getApplicationContext(), getAccounts()); } + private void removeStaleListeners() { + boolean removedListener = false; + synchronized (this.convChangedListenerCount) { + if (this.mOnConversationUpdate != null) { + this.mOnConversationUpdate = null; + this.convChangedListenerCount = 0; + this.mNotificationService.setIsInForeground(false); + removedListener = true; + } + } + synchronized (this.accountChangedListenerCount) { + if (this.mOnAccountUpdate != null) { + this.mOnAccountUpdate = null; + this.accountChangedListenerCount = 0; + removedListener = true; + } + } + synchronized (this.rosterChangedListenerCount) { + if (this.mOnRosterUpdate != null) { + this.mOnRosterUpdate = null; + this.rosterChangedListenerCount = 0; + removedListener = true; + } + } + if (removedListener) { + final String msg = "removed stale listeners"; + Log.d(Config.LOGTAG, msg); + checkListeners(); + try { + OutputStream os = openFileOutput("stacktrace.txt", MODE_PRIVATE); + os.write(msg.getBytes()); + os.flush(); + os.close(); + } catch (final FileNotFoundException ignored) { + + } catch (final IOException ignored) { + } + } + } + public void setOnConversationListChangedListener( OnConversationUpdate listener) { - if (!isScreenOn()) { + /*if (!isScreenOn()) { Log.d(Config.LOGTAG, - "ignoring setOnConversationListChangedListener"); + "ignoring setOnConversationListChangedListener"); return; - } + }*/ synchronized (this.convChangedListenerCount) { if (checkListeners()) { switchToForeground(); @@ -1055,7 +1149,7 @@ public class XmppConnectionService extends Service { this.mNotificationService.setIsInForeground(true); this.convChangedListenerCount++; } - } + } public void removeOnConversationListChangedListener() { synchronized (this.convChangedListenerCount) { @@ -1072,10 +1166,10 @@ public class XmppConnectionService extends Service { } public void setOnAccountListChangedListener(OnAccountUpdate listener) { - if (!isScreenOn()) { + /*if (!isScreenOn()) { Log.d(Config.LOGTAG, "ignoring setOnAccountListChangedListener"); return; - } + }*/ synchronized (this.accountChangedListenerCount) { if (checkListeners()) { switchToForeground(); @@ -1099,10 +1193,10 @@ public class XmppConnectionService extends Service { } public void setOnRosterUpdateListener(OnRosterUpdate listener) { - if (!isScreenOn()) { + /*if (!isScreenOn()) { Log.d(Config.LOGTAG, "ignoring setOnRosterUpdateListener"); return; - } + }*/ synchronized (this.rosterChangedListenerCount) { if (checkListeners()) { switchToForeground(); @@ -1132,7 +1226,7 @@ public class XmppConnectionService extends Service { private void switchToForeground() { for (Account account : getAccounts()) { - if (account.getStatus() == Account.STATUS_ONLINE) { + if (account.getStatus() == Account.State.ONLINE) { XmppConnection connection = account.getXmppConnection(); if (connection != null && connection.getFeatures().csi()) { connection.sendActive(); @@ -1144,7 +1238,7 @@ public class XmppConnectionService extends Service { private void switchToBackground() { for (Account account : getAccounts()) { - if (account.getStatus() == Account.STATUS_ONLINE) { + if (account.getStatus() == Account.State.ONLINE) { XmppConnection connection = account.getXmppConnection(); if (connection != null && connection.getFeatures().csi()) { connection.sendInactive(); @@ -1157,18 +1251,17 @@ public class XmppConnectionService extends Service { private boolean isScreenOn() { PowerManager pm = (PowerManager) this - .getSystemService(Context.POWER_SERVICE); + .getSystemService(Context.POWER_SERVICE); return pm.isScreenOn(); } public void connectMultiModeConversations(Account account) { List<Conversation> conversations = getConversations(); - for (int i = 0; i < conversations.size(); i++) { - Conversation conversation = conversations.get(i); + for (Conversation conversation : conversations) { if ((conversation.getMode() == Conversation.MODE_MULTI) && (conversation.getAccount() == account)) { joinMuc(conversation); - } + } } } @@ -1176,14 +1269,14 @@ public class XmppConnectionService extends Service { Account account = conversation.getAccount(); account.pendingConferenceJoins.remove(conversation); account.pendingConferenceLeaves.remove(conversation); - if (account.getStatus() == Account.STATUS_ONLINE) { + if (account.getStatus() == Account.State.ONLINE) { Log.d(Config.LOGTAG, "joining conversation " + conversation.getContactJid()); String nick = conversation.getMucOptions().getProposedNick(); conversation.getMucOptions().setJoinNick(nick); PresencePacket packet = new PresencePacket(); - String joinJid = conversation.getMucOptions().getJoinJid(); - packet.setAttribute("to", conversation.getMucOptions().getJoinJid()); + final Jid joinJid = conversation.getMucOptions().getJoinJid(); + packet.setTo(conversation.getMucOptions().getJoinJid()); Element x = new Element("x"); x.setAttribute("xmlns", "http://jabber.org/protocol/muc"); if (conversation.getMucOptions().getPassword() != null) { @@ -1215,9 +1308,6 @@ public class XmppConnectionService extends Service { } } - private OnRenameListener renameListener = null; - private IqGenerator mIqGenerator = new IqGenerator(this); - public void setOnRenameListener(OnRenameListener listener) { this.renameListener = listener; } @@ -1260,8 +1350,8 @@ public class XmppConnectionService extends Service { }); options.flagAboutToRename(); PresencePacket packet = new PresencePacket(); - packet.setAttribute("to", options.getJoinJid()); - packet.setAttribute("from", conversation.getAccount().getFullJid()); + packet.setTo(options.getJoinJid()); + packet.setFrom(conversation.getAccount().getJid()); String sig = account.getPgpSignature(); if (sig != null) { @@ -1272,7 +1362,7 @@ public class XmppConnectionService extends Service { } else { conversation.setContactJid(options.getJoinJid()); databaseBackend.updateConversation(conversation); - if (conversation.getAccount().getStatus() == Account.STATUS_ONLINE) { + if (conversation.getAccount().getStatus() == Account.State.ONLINE) { Bookmark bookmark = conversation.getBookmark(); if (bookmark != null) { bookmark.setNick(nick); @@ -1287,15 +1377,15 @@ public class XmppConnectionService extends Service { Account account = conversation.getAccount(); account.pendingConferenceJoins.remove(conversation); account.pendingConferenceLeaves.remove(conversation); - if (account.getStatus() == Account.STATUS_ONLINE) { + if (account.getStatus() == Account.State.ONLINE) { PresencePacket packet = new PresencePacket(); - packet.setAttribute("to", conversation.getMucOptions().getJoinJid()); - packet.setAttribute("from", conversation.getAccount().getFullJid()); + packet.setTo(conversation.getMucOptions().getJoinJid()); + packet.setFrom(conversation.getAccount().getJid()); packet.setAttribute("type", "unavailable"); sendPresencePacket(conversation.getAccount(), packet); conversation.getMucOptions().setOffline(); conversation.deregisterWithBookmark(); - Log.d(Config.LOGTAG, conversation.getAccount().getJid() + Log.d(Config.LOGTAG, conversation.getAccount().getJid().toBareJid() + ": leaving muc " + conversation.getContactJid()); } else { account.pendingConferenceLeaves.add(conversation); @@ -1303,18 +1393,17 @@ public class XmppConnectionService extends Service { } public void disconnect(Account account, boolean force) { - if ((account.getStatus() == Account.STATUS_ONLINE) - || (account.getStatus() == Account.STATUS_DISABLED)) { + if ((account.getStatus() == Account.State.ONLINE) + || (account.getStatus() == Account.State.DISABLED)) { if (!force) { List<Conversation> conversations = getConversations(); - for (int i = 0; i < conversations.size(); i++) { - Conversation conversation = conversations.get(i); + for (Conversation conversation : conversations) { if (conversation.getAccount() == account) { if (conversation.getMode() == Conversation.MODE_MULTI) { leaveMuc(conversation); } else { if (conversation.endOtrIfNeeded()) { - Log.d(Config.LOGTAG, account.getJid() + Log.d(Config.LOGTAG, account.getJid().toBareJid() + ": ended otr session with " + conversation.getContactJid()); } @@ -1323,7 +1412,7 @@ public class XmppConnectionService extends Service { } } account.getXmppConnection().disconnect(force); - } + } } @Override @@ -1362,26 +1451,30 @@ public class XmppConnectionService extends Service { List<Message> messages = conversation.getMessages(); Session otrSession = conversation.getOtrSession(); Log.d(Config.LOGTAG, - account.getJid() + " otr session established with " - + conversation.getContactJid() + "/" - + otrSession.getSessionID().getUserID()); - for (int i = 0; i < messages.size(); ++i) { - Message msg = messages.get(i); + account.getJid().toBareJid() + " otr session established with " + + conversation.getContactJid() + "/" + + otrSession.getSessionID().getUserID()); + for (Message msg : messages) { if ((msg.getStatus() == Message.STATUS_UNSEND || msg.getStatus() == Message.STATUS_WAITING) && (msg.getEncryption() == Message.ENCRYPTION_OTR)) { - msg.setPresence(otrSession.getSessionID().getUserID()); + SessionID id = otrSession.getSessionID(); + try { + msg.setCounterpart(Jid.fromString(id.getAccountID() + "/" + id.getUserID())); + } catch (InvalidJidException e) { + break; + } if (msg.getType() == Message.TYPE_TEXT) { MessagePacket outPacket = mMessageGenerator - .generateOtrChat(msg, true); + .generateOtrChat(msg, true); if (outPacket != null) { msg.setStatus(Message.STATUS_SEND); databaseBackend.updateMessage(msg); sendMessagePacket(account, outPacket); } - } else if (msg.getType() == Message.TYPE_IMAGE) { + } else if (msg.getType() == Message.TYPE_IMAGE || msg.getType() == Message.TYPE_FILE) { mJingleConnectionManager.createNewConnection(msg); } - } + } } updateConversationUi(); } @@ -1394,15 +1487,15 @@ public class XmppConnectionService extends Service { if (otrSession != null) { MessagePacket packet = new MessagePacket(); packet.setType(MessagePacket.TYPE_CHAT); - packet.setFrom(account.getFullJid()); + packet.setFrom(account.getJid()); packet.addChild("private", "urn:xmpp:carbons:2"); packet.addChild("no-copy", "urn:xmpp:hints"); - packet.setTo(otrSession.getSessionID().getAccountID() + "/" + packet.setAttribute("to", otrSession.getSessionID().getAccountID() + "/" + otrSession.getSessionID().getUserID()); try { packet.setBody(otrSession .transformSending(CryptoHelper.FILETRANSFER - + CryptoHelper.bytesToHex(symmetricKey))); + + CryptoHelper.bytesToHex(symmetricKey))); sendMessagePacket(account, packet); conversation.setSymmetricKey(symmetricKey); return true; @@ -1417,11 +1510,11 @@ public class XmppConnectionService extends Service { contact.resetOption(Contact.Options.DIRTY_DELETE); contact.setOption(Contact.Options.DIRTY_PUSH); Account account = contact.getAccount(); - if (account.getStatus() == Account.STATUS_ONLINE) { + if (account.getStatus() == Account.State.ONLINE) { boolean ask = contact.getOption(Contact.Options.ASKING); boolean sendUpdates = contact - .getOption(Contact.Options.PENDING_SUBSCRIPTION_REQUEST) - && contact.getOption(Contact.Options.PREEMPTIVE_GRANT); + .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); @@ -1441,7 +1534,7 @@ public class XmppConnectionService extends Service { final Bitmap.CompressFormat format = Config.AVATAR_FORMAT; final int size = Config.AVATAR_SIZE; final Avatar avatar = getFileBackend() - .getPepAvatar(image, size, format); + .getPepAvatar(image, size, format); if (avatar != null) { avatar.height = size; avatar.width = size; @@ -1463,7 +1556,7 @@ public class XmppConnectionService extends Service { public void onIqPacketReceived(Account account, IqPacket result) { if (result.getType() == IqPacket.TYPE_RESULT) { IqPacket packet = XmppConnectionService.this.mIqGenerator - .publishAvatarMetadata(avatar); + .publishAvatarMetadata(avatar); sendIqPacket(account, packet, new OnIqPacketReceived() { @Override @@ -1504,13 +1597,13 @@ public class XmppConnectionService extends Service { @Override public void onIqPacketReceived(Account account, IqPacket result) { - final String ERROR = account.getJid() - + ": fetching avatar for " + avatar.owner + " failed "; + final String ERROR = account.getJid().toBareJid() + + ": fetching avatar for " + avatar.owner + " failed "; if (result.getType() == IqPacket.TYPE_RESULT) { avatar.image = mIqParser.avatarData(result); if (avatar.image != null) { if (getFileBackend().save(avatar)) { - if (account.getJid().equals(avatar.owner)) { + if (account.getJid().toBareJid().equals(avatar.owner)) { if (account.setAvatar(avatar.getFilename())) { databaseBackend.updateAccount(account); } @@ -1519,7 +1612,7 @@ public class XmppConnectionService extends Service { updateAccountUi(); } else { Contact contact = account.getRoster() - .getContact(avatar.owner); + .getContact(avatar.owner); contact.setAvatar(avatar.getFilename()); getAvatarService().clear(contact); updateConversationUi(); @@ -1528,7 +1621,7 @@ public class XmppConnectionService extends Service { if (callback != null) { callback.success(avatar); } - Log.d(Config.LOGTAG, account.getJid() + Log.d(Config.LOGTAG, account.getJid().toBareJid() + ": succesfully fetched avatar for " + avatar.owner); return; @@ -1568,7 +1661,7 @@ public class XmppConnectionService extends Service { if (items != null) { Avatar avatar = Avatar.parseMetadata(items); if (avatar != null) { - avatar.owner = account.getJid(); + avatar.owner = account.getJid().toBareJid(); if (fileBackend.isAvatarCached(avatar)) { if (account.setAvatar(avatar.getFilename())) { databaseBackend.updateAccount(account); @@ -1593,10 +1686,10 @@ public class XmppConnectionService extends Service { contact.resetOption(Contact.Options.DIRTY_PUSH); contact.setOption(Contact.Options.DIRTY_DELETE); Account account = contact.getAccount(); - if (account.getStatus() == Account.STATUS_ONLINE) { + if (account.getStatus() == Account.State.ONLINE) { IqPacket iq = new IqPacket(IqPacket.TYPE_SET); Element item = iq.query("jabber:iq:roster").addChild("item"); - item.setAttribute("jid", contact.getJid()); + item.setAttribute("jid", contact.getJid().toString()); item.setAttribute("subscription", "remove"); account.getXmppConnection().sendIqPacket(iq, null); } @@ -1642,14 +1735,14 @@ public class XmppConnectionService extends Service { if (message.getType() != Message.TYPE_IMAGE && message.getStatus() == Message.STATUS_UNSEND) { markMessage(message, Message.STATUS_WAITING); - } + } } } } } - public boolean markMessage(Account account, String recipient, String uuid, - int status) { + public boolean markMessage(final Account account, final Jid recipient, final String uuid, + final int status) { if (uuid == null) { return false; } else { @@ -1657,7 +1750,7 @@ public class XmppConnectionService extends Service { if (conversation.getContactJid().equals(recipient) && conversation.getAccount().equals(account)) { return markMessage(conversation, uuid, status); - } + } } return false; } @@ -1671,10 +1764,10 @@ public class XmppConnectionService extends Service { for (Message message : conversation.getMessages()) { if (uuid.equals(message.getUuid()) || (message.getStatus() >= Message.STATUS_SEND && uuid - .equals(message.getRemoteMsgId()))) { + .equals(message.getRemoteMsgId()))) { markMessage(message, status); return true; - } + } } return false; } @@ -1683,9 +1776,9 @@ public class XmppConnectionService extends Service { public void markMessage(Message message, int status) { if (status == Message.STATUS_SEND_FAILED && (message.getStatus() == Message.STATUS_SEND_RECEIVED || message - .getStatus() == Message.STATUS_SEND_DISPLAYED)) { + .getStatus() == Message.STATUS_SEND_DISPLAYED)) { return; - } + } message.setStatus(status); databaseBackend.updateMessage(message); updateConversationUi(); @@ -1693,7 +1786,7 @@ public class XmppConnectionService extends Service { public SharedPreferences getPreferences() { return PreferenceManager - .getDefaultSharedPreferences(getApplicationContext()); + .getDefaultSharedPreferences(getApplicationContext()); } public boolean forceEncryption() { @@ -1730,9 +1823,9 @@ public class XmppConnectionService extends Service { } } - public Account findAccountByJid(String accountJid) { + public Account findAccountByJid(final Jid accountJid) { for (Account account : this.accounts) { - if (account.getJid().equals(accountJid)) { + if (account.getJid().toBareJid().equals(accountJid)) { return account; } } @@ -1753,10 +1846,10 @@ public class XmppConnectionService extends Service { String id = conversation.getLatestMarkableMessageId(); conversation.markRead(); if (confirmMessages() && id != null && calledByUi) { - Log.d(Config.LOGTAG, conversation.getAccount().getJid() + Log.d(Config.LOGTAG, conversation.getAccount().getJid().toBareJid() + ": sending read marker for " + conversation.getName()); Account account = conversation.getAccount(); - String to = conversation.getContactJid(); + final Jid to = conversation.getContactJid(); this.sendMessagePacket(conversation.getAccount(), mMessageGenerator.confirm(account, to, id)); } @@ -1770,7 +1863,7 @@ public class XmppConnectionService extends Service { if (message.getEncryption() == Message.ENCRYPTION_OTR && message.getStatus() == Message.STATUS_WAITING) { markMessage(message, Message.STATUS_SEND_FAILED); - } + } } } @@ -1791,9 +1884,9 @@ public class XmppConnectionService extends Service { } public void replyWithNotAcceptable(Account account, MessagePacket packet) { - if (account.getStatus() == Account.STATUS_ONLINE) { + if (account.getStatus() == Account.State.ONLINE) { MessagePacket error = this.mMessageGenerator - .generateNotAcceptable(packet); + .generateNotAcceptable(packet); sendMessagePacket(account, error); } } @@ -1810,14 +1903,14 @@ public class XmppConnectionService extends Service { } public List<String> getKnownHosts() { - List<String> hosts = new ArrayList<String>(); + List<String> hosts = new ArrayList<>(); for (Account account : getAccounts()) { - if (!hosts.contains(account.getServer())) { - hosts.add(account.getServer()); + if (!hosts.contains(account.getServer().toString())) { + hosts.add(account.getServer().toString()); } for (Contact contact : account.getRoster().getContacts()) { if (contact.showInRoster()) { - String server = contact.getServer(); + final String server = contact.getServer().toString(); if (server != null && !hosts.contains(server)) { hosts.add(server); } @@ -1828,7 +1921,7 @@ public class XmppConnectionService extends Service { } public List<String> getKnownConferenceHosts() { - ArrayList<String> mucServers = new ArrayList<String>(); + ArrayList<String> mucServers = new ArrayList<>(); for (Account account : accounts) { if (account.getXmppConnection() != null) { String server = account.getXmppConnection().getMucServer(); @@ -1878,20 +1971,8 @@ public class XmppConnectionService extends Service { return this.mJingleConnectionManager; } - public interface OnConversationUpdate { - public void onConversationUpdate(); - } - - public interface OnAccountUpdate { - public void onAccountUpdate(); - } - - public interface OnRosterUpdate { - public void onRosterUpdate(); - } - public List<Contact> findContacts(String jid) { - ArrayList<Contact> contacts = new ArrayList<Contact>(); + ArrayList<Contact> contacts = new ArrayList<>(); for (Account account : getAccounts()) { if (!account.isOptionSet(Account.OPTION_DISABLED)) { Contact contact = account.getRoster().getContactFromRoster(jid); @@ -1911,29 +1992,10 @@ public class XmppConnectionService extends Service { return this.mHttpConnectionManager; } - private class DeletedDownloadable implements Downloadable { - - @Override - public boolean start() { - return false; - } - - @Override - public int getStatus() { - return Downloadable.STATUS_DELETED; - } - - @Override - public long getFileSize() { - return 0; - } - - } - public void resendFailedMessages(Message message) { - List<Message> messages = new ArrayList<Message>(); + List<Message> messages = new ArrayList<>(); Message current = message; - while(current.getStatus() == Message.STATUS_SEND_FAILED) { + while (current.getStatus() == Message.STATUS_SEND_FAILED) { messages.add(current); if (current.mergeable(current.next())) { current = current.next(); @@ -1941,9 +2003,27 @@ public class XmppConnectionService extends Service { break; } } - for(Message msg: messages) { + for (Message msg : messages) { markMessage(msg, Message.STATUS_WAITING); this.resendMessage(msg); } } + + public interface OnConversationUpdate { + public void onConversationUpdate(); + } + + public interface OnAccountUpdate { + public void onAccountUpdate(); + } + + public interface OnRosterUpdate { + public void onRosterUpdate(); + } + + public class XmppConnectionBinder extends Binder { + public XmppConnectionService getService() { + return XmppConnectionService.this; + } + } } |