aboutsummaryrefslogtreecommitdiffstats
path: root/src/main/java/eu/siacs/conversations/services/XmppConnectionService.java
diff options
context:
space:
mode:
Diffstat (limited to 'src/main/java/eu/siacs/conversations/services/XmppConnectionService.java')
-rw-r--r--src/main/java/eu/siacs/conversations/services/XmppConnectionService.java178
1 files changed, 142 insertions, 36 deletions
diff --git a/src/main/java/eu/siacs/conversations/services/XmppConnectionService.java b/src/main/java/eu/siacs/conversations/services/XmppConnectionService.java
index e34f9bd7..ca182867 100644
--- a/src/main/java/eu/siacs/conversations/services/XmppConnectionService.java
+++ b/src/main/java/eu/siacs/conversations/services/XmppConnectionService.java
@@ -16,6 +16,7 @@ import android.os.Binder;
import android.os.Bundle;
import android.os.FileObserver;
import android.os.IBinder;
+import android.os.Looper;
import android.os.PowerManager;
import android.os.PowerManager.WakeLock;
import android.os.SystemClock;
@@ -85,6 +86,7 @@ import eu.siacs.conversations.xmpp.OnPresencePacketReceived;
import eu.siacs.conversations.xmpp.OnStatusChanged;
import eu.siacs.conversations.xmpp.OnUpdateBlocklist;
import eu.siacs.conversations.xmpp.XmppConnection;
+import eu.siacs.conversations.xmpp.chatstate.ChatState;
import eu.siacs.conversations.xmpp.forms.Data;
import eu.siacs.conversations.xmpp.forms.Field;
import eu.siacs.conversations.xmpp.jid.InvalidJidException;
@@ -102,6 +104,8 @@ public class XmppConnectionService extends Service implements OnPhoneContactsLoa
public static final String ACTION_CLEAR_NOTIFICATION = "clear_notification";
public static final String ACTION_DISABLE_FOREGROUND = "disable_foreground";
private static final String ACTION_MERGE_PHONE_CONTACTS = "merge_phone_contacts";
+ public static final String ACTION_TRY_AGAIN = "try_again";
+ public static final String ACTION_DISABLE_ACCOUNT = "disable_account";
private ContentObserver contactObserver = new ContentObserver(null) {
@Override
public void onChange(boolean selfChange) {
@@ -275,6 +279,11 @@ public class XmppConnectionService extends Service implements OnPhoneContactsLoa
private LruCache<String, Bitmap> mBitmapCache;
private Thread mPhoneContactMergerThread;
+ private boolean mRestoredFromDatabase = false;
+ public boolean areMessagesInitialized() {
+ return this.mRestoredFromDatabase;
+ }
+
public PgpEngine getPgpEngine() {
if (pgpServiceConnection.isBound()) {
if (this.mPgpEngine == null) {
@@ -297,6 +306,24 @@ public class XmppConnectionService extends Service implements OnPhoneContactsLoa
return this.mAvatarService;
}
+ public void attachLocationToConversation(final Conversation conversation,
+ final Uri uri,
+ final UiCallback<Message> callback) {
+ int encryption = conversation.getNextEncryption(forceEncryption());
+ if (encryption == Message.ENCRYPTION_PGP) {
+ encryption = Message.ENCRYPTION_DECRYPTED;
+ }
+ Message message = new Message(conversation,uri.toString(),encryption);
+ if (conversation.getNextCounterpart() != null) {
+ message.setCounterpart(conversation.getNextCounterpart());
+ }
+ if (encryption == Message.ENCRYPTION_DECRYPTED) {
+ getPgpEngine().encrypt(message,callback);
+ } else {
+ callback.success(message);
+ }
+ }
+
public void attachFileToConversation(final Conversation conversation,
final Uri uri,
final UiCallback<Message> callback) {
@@ -386,7 +413,11 @@ public class XmppConnectionService extends Service implements OnPhoneContactsLoa
if (action != null) {
switch (action) {
case ACTION_MERGE_PHONE_CONTACTS:
- PhoneHelper.loadPhoneContacts(getApplicationContext(), new CopyOnWriteArrayList<Bundle>(), this);
+ if (mRestoredFromDatabase) {
+ PhoneHelper.loadPhoneContacts(getApplicationContext(),
+ new CopyOnWriteArrayList<Bundle>(),
+ this);
+ }
return START_STICKY;
case Intent.ACTION_SHUTDOWN:
logoutAndSave();
@@ -398,6 +429,28 @@ public class XmppConnectionService extends Service implements OnPhoneContactsLoa
getPreferences().edit().putBoolean("keep_foreground_service",false).commit();
toggleForegroundService();
break;
+ case ACTION_TRY_AGAIN:
+ for(Account account : accounts) {
+ if (account.hasErrorStatus()) {
+ final XmppConnection connection = account.getXmppConnection();
+ if (connection != null) {
+ connection.resetAttemptCount();
+ }
+ }
+ }
+ break;
+ case ACTION_DISABLE_ACCOUNT:
+ try {
+ String jid = intent.getStringExtra("account");
+ Account account = jid == null ? null : findAccountByJid(Jid.fromString(jid));
+ if (account != null) {
+ account.setOption(Account.OPTION_DISABLED,true);
+ updateAccount(account);
+ }
+ } catch (final InvalidJidException ignored) {
+ break;
+ }
+ break;
}
}
this.wakeLock.acquire();
@@ -432,10 +485,7 @@ public class XmppConnectionService extends Service implements OnPhoneContactsLoa
this.scheduleWakeUpCall((int) (msToNextPing / 1000), account.getUuid().hashCode());
}
} else if (account.getStatus() == Account.State.OFFLINE) {
- if (account.getXmppConnection() == null) {
- account.setXmppConnection(this.createConnection(account));
- }
- new Thread(account.getXmppConnection()).start();
+ reconnectAccount(account,true);
} else if (account.getStatus() == Account.State.CONNECTING) {
long timeout = Config.CONNECT_TIMEOUT - ((SystemClock.elapsedRealtime() - account.getXmppConnection().getLastConnect()) / 1000);
if (timeout < 0) {
@@ -499,10 +549,8 @@ public class XmppConnectionService extends Service implements OnPhoneContactsLoa
for (final Account account : this.accounts) {
account.initOtrEngine(this);
- this.databaseBackend.readRoster(account.getRoster());
}
- initConversations();
- PhoneHelper.loadPhoneContacts(getApplicationContext(),new CopyOnWriteArrayList<Bundle>(), this);
+ restoreFromDatabase();
getContentResolver().registerContentObserver(ContactsContract.Contacts.CONTENT_URI, true, contactObserver);
this.fileObserver.startWatching();
@@ -574,6 +622,13 @@ public class XmppConnectionService extends Service implements OnPhoneContactsLoa
return connection;
}
+ public void sendChatState(Conversation conversation) {
+ if (sendChatStates()) {
+ MessagePacket packet = mMessageGenerator.generateChatState(conversation);
+ sendMessagePacket(conversation.getAccount(), packet);
+ }
+ }
+
public void sendMessage(final Message message) {
final Account account = message.getConversation().getAccount();
account.deactivateGracePeriod();
@@ -674,6 +729,11 @@ public class XmppConnectionService extends Service implements OnPhoneContactsLoa
}
}
if ((send) && (packet != null)) {
+ if (conv.setOutgoingChatState(Config.DEFAULT_CHATSTATE)) {
+ if (this.sendChatStates()) {
+ packet.addChild(ChatState.toElement(conv.getOutgoingChatState()));
+ }
+ }
sendMessagePacket(account, packet);
}
updateConversationUi();
@@ -755,6 +815,11 @@ public class XmppConnectionService extends Service implements OnPhoneContactsLoa
} else {
markMessage(message, Message.STATUS_UNSEND);
}
+ if (message.getConversation().setOutgoingChatState(Config.DEFAULT_CHATSTATE)) {
+ if (this.sendChatStates()) {
+ packet.addChild(ChatState.toElement(message.getConversation().getOutgoingChatState()));
+ }
+ }
sendMessagePacket(account, packet);
}
}
@@ -855,7 +920,7 @@ public class XmppConnectionService extends Service implements OnPhoneContactsLoa
mPhoneContactMergerThread.start();
}
- private void initConversations() {
+ private void restoreFromDatabase() {
synchronized (this.conversations) {
final Map<String, Account> accountLookupTable = new Hashtable<>();
for (Account account : this.accounts) {
@@ -865,9 +930,29 @@ public class XmppConnectionService extends Service implements OnPhoneContactsLoa
for (Conversation conversation : this.conversations) {
Account account = accountLookupTable.get(conversation.getAccountUuid());
conversation.setAccount(account);
- conversation.addAll(0, databaseBackend.getMessages(conversation, Config.PAGE_SIZE));
- checkDeletedFiles(conversation);
}
+ new Thread(new Runnable() {
+ @Override
+ public void run() {
+ Log.d(Config.LOGTAG,"restoring roster");
+ for(Account account : accounts) {
+ databaseBackend.readRoster(account.getRoster());
+ }
+ getBitmapCache().evictAll();
+ Looper.prepare();
+ PhoneHelper.loadPhoneContacts(getApplicationContext(),
+ new CopyOnWriteArrayList<Bundle>(),
+ XmppConnectionService.this);
+ Log.d(Config.LOGTAG,"restoring messages");
+ for (Conversation conversation : conversations) {
+ conversation.addAll(0, databaseBackend.getMessages(conversation, Config.PAGE_SIZE));
+ checkDeletedFiles(conversation);
+ }
+ mRestoredFromDatabase = true;
+ Log.d(Config.LOGTAG,"restored all messages");
+ updateConversationUi();
+ }
+ }).start();
}
}
@@ -1069,7 +1154,7 @@ public class XmppConnectionService extends Service implements OnPhoneContactsLoa
account.initOtrEngine(this);
databaseBackend.createAccount(account);
this.accounts.add(account);
- this.reconnectAccount(account, false);
+ this.reconnectAccountInBackground(account);
updateAccountUi();
}
@@ -1274,6 +1359,9 @@ public class XmppConnectionService extends Service implements OnPhoneContactsLoa
}
}
}
+ for(Conversation conversation : getConversations()) {
+ conversation.setIncomingChatState(ChatState.ACTIVE);
+ }
this.mNotificationService.setIsInForeground(false);
Log.d(Config.LOGTAG, "app switched into background");
}
@@ -1902,24 +1990,29 @@ public class XmppConnectionService extends Service implements OnPhoneContactsLoa
}
public void reconnectAccount(final Account account, final boolean force) {
- new Thread(new Runnable() {
+ synchronized (account) {
+ if (account.getXmppConnection() != null) {
+ disconnect(account, force);
+ }
+ if (!account.isOptionSet(Account.OPTION_DISABLED)) {
+ if (account.getXmppConnection() == null) {
+ account.setXmppConnection(createConnection(account));
+ }
+ Thread thread = new Thread(account.getXmppConnection());
+ thread.start();
+ scheduleWakeUpCall(Config.CONNECT_TIMEOUT, account.getUuid().hashCode());
+ } else {
+ account.getRoster().clearPresences();
+ account.setXmppConnection(null);
+ }
+ }
+ }
+ public void reconnectAccountInBackground(final Account account) {
+ new Thread(new Runnable() {
@Override
public void run() {
- if (account.getXmppConnection() != null) {
- disconnect(account, force);
- }
- if (!account.isOptionSet(Account.OPTION_DISABLED)) {
- if (account.getXmppConnection() == null) {
- account.setXmppConnection(createConnection(account));
- }
- Thread thread = new Thread(account.getXmppConnection());
- thread.start();
- scheduleWakeUpCall(Config.CONNECT_TIMEOUT, account.getUuid().hashCode());
- } else {
- account.getRoster().clearPresences();
- account.setXmppConnection(null);
- }
+ reconnectAccount(account,false);
}
}).start();
}
@@ -1943,19 +2036,20 @@ public class XmppConnectionService extends Service implements OnPhoneContactsLoa
}
}
- public boolean markMessage(final Account account, final Jid recipient, final String uuid,
- final int status) {
+ public Message markMessage(final Account account, final Jid recipient, final String uuid, final int status) {
if (uuid == null) {
- return false;
- } else {
- for (Conversation conversation : getConversations()) {
- if (conversation.getJid().equals(recipient)
- && conversation.getAccount().equals(account)) {
- return markMessage(conversation, uuid, status);
+ return null;
+ }
+ for (Conversation conversation : getConversations()) {
+ if (conversation.getJid().toBareJid().equals(recipient) && conversation.getAccount() == account) {
+ final Message message = conversation.findSentMessageWithUuid(uuid);
+ if (message != null) {
+ markMessage(message, status);
}
+ return message;
}
- return false;
}
+ return null;
}
public boolean markMessage(Conversation conversation, String uuid,
@@ -1997,6 +2091,10 @@ public class XmppConnectionService extends Service implements OnPhoneContactsLoa
return getPreferences().getBoolean("confirm_messages", true);
}
+ public boolean sendChatStates() {
+ return getPreferences().getBoolean("chat_states", false);
+ }
+
public boolean saveEncryptedMessages() {
return !getPreferences().getBoolean("dont_save_encrypted", false);
}
@@ -2005,6 +2103,14 @@ public class XmppConnectionService extends Service implements OnPhoneContactsLoa
return getPreferences().getBoolean("indicate_received", false);
}
+ public int unreadCount() {
+ int count = 0;
+ for(Conversation conversation : getConversations()) {
+ count += conversation.unreadCount();
+ }
+ return count;
+ }
+
public void updateConversationUi() {
if (mOnConversationUpdate != null) {
mOnConversationUpdate.onConversationUpdate();