@@ -297,7 +297,7 @@ public class XmppConnectionService extends Service {
if (loggedInSuccessfully) {
if (!TextUtils.isEmpty(account.getDisplayName())) {
- Log.d(Config.LOGTAG,account.getJid().asBareJid()+": display name wasn't empty on first log in. publishing");
+ Log.d(Config.LOGTAG, account.getJid().asBareJid() + ": display name wasn't empty on first log in. publishing");
publishDisplayName(account);
}
}
@@ -526,8 +526,8 @@ public class XmppConnectionService extends Service {
message.setCounterpart(conversation.getNextCounterpart());
message.setType(Message.TYPE_FILE);
}
- Log.d(Config.LOGTAG,"attachFile: type="+message.getType());
- Log.d(Config.LOGTAG,"counterpart="+message.getCounterpart());
+ Log.d(Config.LOGTAG, "attachFile: type=" + message.getType());
+ Log.d(Config.LOGTAG, "counterpart=" + message.getCounterpart());
final AttachFileToConversationRunnable runnable = new AttachFileToConversationRunnable(this, uri, type, message, callback);
if (runnable.isVideoMessage()) {
mVideoCompressionExecutor.execute(runnable);
@@ -558,7 +558,7 @@ public class XmppConnectionService extends Service {
message.setCounterpart(conversation.getNextCounterpart());
message.setType(Message.TYPE_IMAGE);
}
- Log.d(Config.LOGTAG,"attachImage: type="+message.getType());
+ Log.d(Config.LOGTAG, "attachImage: type=" + message.getType());
mFileAddingExecutor.execute(() -> {
try {
getFileBackend().copyImageToPrivateStorage(message, uri);
@@ -601,7 +601,7 @@ public class XmppConnectionService extends Service {
final String action = intent == null ? null : intent.getAction();
final boolean needsForegroundService = intent != null && intent.getBooleanExtra(EventReceiver.EXTRA_NEEDS_FOREGROUND_SERVICE, false);
if (needsForegroundService) {
- Log.d(Config.LOGTAG,"toggle forced foreground service after receiving event (action="+action+")");
+ Log.d(Config.LOGTAG, "toggle forced foreground service after receiving event (action=" + action + ")");
toggleForegroundService(true);
}
String pushedAccountHash = null;
@@ -837,12 +837,12 @@ public class XmppConnectionService extends Service {
}
private void checkMucStillJoined(final Account account, final String hash, final String androidId) {
- for(final Conversation conversation : this.conversations) {
+ for (final Conversation conversation : this.conversations) {
if (conversation.getAccount() == account && conversation.getMode() == Conversational.MODE_MULTI) {
Jid jid = conversation.getJid().asBareJid();
final String currentHash = CryptoHelper.getFingerprint(jid, androidId);
if (currentHash.equals(hash)) {
- Log.d(Config.LOGTAG,account.getJid().asBareJid()+": received cloud push notification for MUC "+jid);
+ Log.d(Config.LOGTAG, account.getJid().asBareJid() + ": received cloud push notification for MUC " + jid);
return;
}
}
@@ -1050,7 +1050,7 @@ public class XmppConnectionService extends Service {
try {
Security.insertProviderAt(Conscrypt.newProvider(), 1);
} catch (Throwable throwable) {
- Log.e(Config.LOGTAG,"unable to initialize security provider", throwable);
+ Log.e(Config.LOGTAG, "unable to initialize security provider", throwable);
}
Resolver.init(this);
this.mRandom = new SecureRandom();
@@ -1137,7 +1137,7 @@ public class XmppConnectionService extends Service {
final long start = SystemClock.elapsedRealtime();
final List<DatabaseBackend.FilePathInfo> relativeFilePaths = databaseBackend.getFilePathInfo();
final List<DatabaseBackend.FilePathInfo> changed = new ArrayList<>();
- for(final DatabaseBackend.FilePathInfo filePath : relativeFilePaths) {
+ for (final DatabaseBackend.FilePathInfo filePath : relativeFilePaths) {
if (destroyed) {
Log.d(Config.LOGTAG, "Stop checking for deleted files because service has been destroyed");
return;
@@ -1148,7 +1148,7 @@ public class XmppConnectionService extends Service {
}
}
final long duration = SystemClock.elapsedRealtime() - start;
- Log.d(Config.LOGTAG,"found "+changed.size()+" changed files on start up. total="+relativeFilePaths.size()+". ("+duration+"ms)");
+ Log.d(Config.LOGTAG, "found " + changed.size() + " changed files on start up. total=" + relativeFilePaths.size() + ". (" + duration + "ms)");
if (changed.size() > 0) {
databaseBackend.markFilesAsChanged(changed);
markChangedFiles(changed);
@@ -1229,7 +1229,7 @@ public class XmppConnectionService extends Service {
if (!mForceForegroundService.get()) {
mNotificationService.dismissForcedForegroundNotification(); //if the channel was changed the previous call might fail
}
- Log.d(Config.LOGTAG,"ForegroundService: "+(status?"on":"off"));
+ Log.d(Config.LOGTAG, "ForegroundService: " + (status ? "on" : "off"));
}
public boolean foregroundNotificationNeedsUpdatingWhenErrorStateChanges() {
@@ -1369,7 +1369,7 @@ public class XmppConnectionService extends Service {
if (QuickConversationsService.isQuicksy() && conversation.getMode() == Conversation.MODE_SINGLE) {
final Contact contact = conversation.getContact();
if (!contact.showInRoster() && contact.getOption(Contact.Options.SYNCED_VIA_OTHER)) {
- Log.d(Config.LOGTAG,account.getJid().asBareJid()+": adding "+contact.getJid()+" on sending message");
+ Log.d(Config.LOGTAG, account.getJid().asBareJid() + ": adding " + contact.getJid() + " on sending message");
createContact(contact, true);
}
}
@@ -1460,7 +1460,7 @@ public class XmppConnectionService extends Service {
message.setBody(decryptedBody);
message.setEncryption(Message.ENCRYPTION_DECRYPTED);
if (!databaseBackend.updateMessage(message, message.getEditedId())) {
- Log.e(Config.LOGTAG,"error updated message in DB after edit");
+ Log.e(Config.LOGTAG, "error updated message in DB after edit");
}
updateConversationUi();
return;
@@ -1500,7 +1500,7 @@ public class XmppConnectionService extends Service {
databaseBackend.createMessage(message);
} else if (message.edited()) {
if (!databaseBackend.updateMessage(message, message.getEditedId())) {
- Log.e(Config.LOGTAG,"error updated message in DB after edit");
+ Log.e(Config.LOGTAG, "error updated message in DB after edit");
}
}
updateConversationUi();
@@ -1526,7 +1526,7 @@ public class XmppConnectionService extends Service {
final boolean pending = account.pendingConferenceJoins.contains(conversation);
final boolean inProgressJoin = inProgress || pending;
if (inProgressJoin) {
- Log.d(Config.LOGTAG,account.getJid().asBareJid()+": holding back message to group. inProgress="+inProgress+", pending="+pending);
+ Log.d(Config.LOGTAG, account.getJid().asBareJid() + ": holding back message to group. inProgress=" + inProgress + ", pending=" + pending);
}
return inProgressJoin;
} else {
@@ -1586,7 +1586,7 @@ public class XmppConnectionService extends Service {
});
}
- public void processBookmarksInitial(Account account, Map<Jid,Bookmark> bookmarks, final boolean pep) {
+ public void processBookmarksInitial(Account account, Map<Jid, Bookmark> bookmarks, final boolean pep) {
final Set<Jid> previousBookmarks = account.getBookmarkedJids();
final boolean synchronizeWithBookmarks = synchronizeWithBookmarks();
for (Bookmark bookmark : bookmarks.values()) {
@@ -1605,7 +1605,7 @@ public class XmppConnectionService extends Service {
public void processDeletedBookmark(Account account, Jid jid) {
final Conversation conversation = find(account, jid);
if (conversation != null && conversation.getMucOptions().getError() == MucOptions.Error.DESTROYED) {
- Log.d(Config.LOGTAG,account.getJid().asBareJid()+": archiving destroyed conference ("+conversation.getJid()+") after receiving pep");
+ Log.d(Config.LOGTAG, account.getJid().asBareJid() + ": archiving destroyed conference (" + conversation.getJid() + ") after receiving pep");
archiveConversation(conversation, false);
}
}
@@ -1619,7 +1619,7 @@ public class XmppConnectionService extends Service {
}
bookmark.setConversation(conversation);
if (pep && synchronizeWithBookmarks && !bookmark.autojoin()) {
- Log.d(Config.LOGTAG,account.getJid().asBareJid()+": archiving conference ("+conversation.getJid()+") after receiving pep");
+ Log.d(Config.LOGTAG, account.getJid().asBareJid() + ": archiving conference (" + conversation.getJid() + ") after receiving pep");
archiveConversation(conversation, false);
} else {
final MucOptions mucOptions = conversation.getMucOptions();
@@ -1627,7 +1627,7 @@ public class XmppConnectionService extends Service {
final String current = mucOptions.getActualNick();
final String proposed = mucOptions.getProposedNick();
if (current != null && !current.equals(proposed)) {
- Log.d(Config.LOGTAG,account.getJid().asBareJid()+": proposed nick changed after bookmark push "+current+"->"+proposed);
+ Log.d(Config.LOGTAG, account.getJid().asBareJid() + ": proposed nick changed after bookmark push " + current + "->" + proposed);
joinMuc(conversation);
}
}
@@ -1661,10 +1661,9 @@ public class XmppConnectionService extends Service {
final XmppConnection connection = account.getXmppConnection();
if (connection.getFeatures().bookmarksConversion()) {
IqPacket request = mIqGenerator.deleteItem(Namespace.BOOKMARKS2, bookmark.getJid().asBareJid().toEscapedString());
- sendIqPacket(account, request, new OnIqPacketReceived() {
- @Override
- public void onIqPacketReceived(Account account, IqPacket packet) {
- Log.d(Config.LOGTAG,packet.toString());
+ sendIqPacket(account, request, (a, response) -> {
+ if (response.getType() == IqPacket.TYPE.ERROR) {
+ Log.d(Config.LOGTAG, a.getJid().asBareJid() + ": unable to delete bookmark " + response.getError());
}
});
} else if (connection.getFeatures().bookmarksConversion()) {
@@ -1691,7 +1690,7 @@ public class XmppConnectionService extends Service {
for (Bookmark bookmark : account.getBookmarks()) {
storage.addChild(bookmark);
}
- pushNodeAndEnforcePublishOptions(account,Namespace.BOOKMARKS,storage, PublishOptions.persistentWhitelistAccess());
+ pushNodeAndEnforcePublishOptions(account, Namespace.BOOKMARKS, storage, PublishOptions.persistentWhitelistAccess());
}
@@ -1705,7 +1704,7 @@ public class XmppConnectionService extends Service {
}
- private void pushNodeAndEnforcePublishOptions(final Account account, final String node, final Element element, final String id, final Bundle options, final boolean retry) {
+ private void pushNodeAndEnforcePublishOptions(final Account account, final String node, final Element element, final String id, final Bundle options, final boolean retry) {
final IqPacket packet = mIqGenerator.publishElement(node, element, id, options);
sendIqPacket(account, packet, (a, response) -> {
if (response.getType() == IqPacket.TYPE.RESULT) {
@@ -1720,81 +1719,81 @@ public class XmppConnectionService extends Service {
@Override
public void onPushFailed() {
- Log.d(Config.LOGTAG,account.getJid().asBareJid()+": unable to push node configuration ("+node+")");
+ Log.d(Config.LOGTAG, account.getJid().asBareJid() + ": unable to push node configuration (" + node + ")");
}
});
} else {
- Log.d(Config.LOGTAG,account.getJid().asBareJid()+": error publishing bookmarks (retry="+Boolean.toString(retry)+") "+response);
+ Log.d(Config.LOGTAG, account.getJid().asBareJid() + ": error publishing bookmarks (retry=" + Boolean.toString(retry) + ") " + response);
}
});
}
- private void restoreFromDatabase() {
- synchronized (this.conversations) {
- final Map<String, Account> accountLookupTable = new Hashtable<>();
- for (Account account : this.accounts) {
- accountLookupTable.put(account.getUuid(), account);
- }
- Log.d(Config.LOGTAG, "restoring conversations...");
- final long startTimeConversationsRestore = SystemClock.elapsedRealtime();
- this.conversations.addAll(databaseBackend.getConversations(Conversation.STATUS_AVAILABLE));
- for (Iterator<Conversation> iterator = conversations.listIterator(); iterator.hasNext(); ) {
- Conversation conversation = iterator.next();
- Account account = accountLookupTable.get(conversation.getAccountUuid());
- if (account != null) {
- conversation.setAccount(account);
- } else {
- Log.e(Config.LOGTAG, "unable to restore Conversations with " + conversation.getJid());
- iterator.remove();
- }
- }
- long diffConversationsRestore = SystemClock.elapsedRealtime() - startTimeConversationsRestore;
- Log.d(Config.LOGTAG, "finished restoring conversations in " + diffConversationsRestore + "ms");
- Runnable runnable = () -> {
- long deletionDate = getAutomaticMessageDeletionDate();
- mLastExpiryRun.set(SystemClock.elapsedRealtime());
- if (deletionDate > 0) {
- Log.d(Config.LOGTAG, "deleting messages that are older than " + AbstractGenerator.getTimestamp(deletionDate));
- databaseBackend.expireOldMessages(deletionDate);
- }
- Log.d(Config.LOGTAG, "restoring roster...");
- for (Account account : accounts) {
- databaseBackend.readRoster(account.getRoster());
- account.initAccountServices(XmppConnectionService.this); //roster needs to be loaded at this stage
- }
- getBitmapCache().evictAll();
- loadPhoneContacts();
- Log.d(Config.LOGTAG, "restoring messages...");
- final long startMessageRestore = SystemClock.elapsedRealtime();
- final Conversation quickLoad = QuickLoader.get(this.conversations);
- if (quickLoad != null) {
- restoreMessages(quickLoad);
- updateConversationUi();
- final long diffMessageRestore = SystemClock.elapsedRealtime() - startMessageRestore;
- Log.d(Config.LOGTAG,"quickly restored "+quickLoad.getName()+" after " + diffMessageRestore + "ms");
- }
- for (Conversation conversation : this.conversations) {
- if (quickLoad != conversation) {
- restoreMessages(conversation);
- }
- }
- mNotificationService.finishBacklog(false);
- restoredFromDatabaseLatch.countDown();
- final long diffMessageRestore = SystemClock.elapsedRealtime() - startMessageRestore;
- Log.d(Config.LOGTAG, "finished restoring messages in " + diffMessageRestore + "ms");
- updateConversationUi();
- };
- mDatabaseReaderExecutor.execute(runnable); //will contain one write command (expiry) but that's fine
- }
- }
-
- private void restoreMessages(Conversation conversation) {
- conversation.addAll(0, databaseBackend.getMessages(conversation, Config.PAGE_SIZE));
- conversation.findUnsentTextMessages(message -> markMessage(message, Message.STATUS_WAITING));
- conversation.findUnreadMessages(message -> mNotificationService.pushFromBacklog(message));
- }
-
- public void loadPhoneContacts() {
+ private void restoreFromDatabase() {
+ synchronized (this.conversations) {
+ final Map<String, Account> accountLookupTable = new Hashtable<>();
+ for (Account account : this.accounts) {
+ accountLookupTable.put(account.getUuid(), account);
+ }
+ Log.d(Config.LOGTAG, "restoring conversations...");
+ final long startTimeConversationsRestore = SystemClock.elapsedRealtime();
+ this.conversations.addAll(databaseBackend.getConversations(Conversation.STATUS_AVAILABLE));
+ for (Iterator<Conversation> iterator = conversations.listIterator(); iterator.hasNext(); ) {
+ Conversation conversation = iterator.next();
+ Account account = accountLookupTable.get(conversation.getAccountUuid());
+ if (account != null) {
+ conversation.setAccount(account);
+ } else {
+ Log.e(Config.LOGTAG, "unable to restore Conversations with " + conversation.getJid());
+ iterator.remove();
+ }
+ }
+ long diffConversationsRestore = SystemClock.elapsedRealtime() - startTimeConversationsRestore;
+ Log.d(Config.LOGTAG, "finished restoring conversations in " + diffConversationsRestore + "ms");
+ Runnable runnable = () -> {
+ long deletionDate = getAutomaticMessageDeletionDate();
+ mLastExpiryRun.set(SystemClock.elapsedRealtime());
+ if (deletionDate > 0) {
+ Log.d(Config.LOGTAG, "deleting messages that are older than " + AbstractGenerator.getTimestamp(deletionDate));
+ databaseBackend.expireOldMessages(deletionDate);
+ }
+ Log.d(Config.LOGTAG, "restoring roster...");
+ for (Account account : accounts) {
+ databaseBackend.readRoster(account.getRoster());
+ account.initAccountServices(XmppConnectionService.this); //roster needs to be loaded at this stage
+ }
+ getBitmapCache().evictAll();
+ loadPhoneContacts();
+ Log.d(Config.LOGTAG, "restoring messages...");
+ final long startMessageRestore = SystemClock.elapsedRealtime();
+ final Conversation quickLoad = QuickLoader.get(this.conversations);
+ if (quickLoad != null) {
+ restoreMessages(quickLoad);
+ updateConversationUi();
+ final long diffMessageRestore = SystemClock.elapsedRealtime() - startMessageRestore;
+ Log.d(Config.LOGTAG, "quickly restored " + quickLoad.getName() + " after " + diffMessageRestore + "ms");
+ }
+ for (Conversation conversation : this.conversations) {
+ if (quickLoad != conversation) {
+ restoreMessages(conversation);
+ }
+ }
+ mNotificationService.finishBacklog(false);
+ restoredFromDatabaseLatch.countDown();
+ final long diffMessageRestore = SystemClock.elapsedRealtime() - startMessageRestore;
+ Log.d(Config.LOGTAG, "finished restoring messages in " + diffMessageRestore + "ms");
+ updateConversationUi();
+ };
+ mDatabaseReaderExecutor.execute(runnable); //will contain one write command (expiry) but that's fine
+ }
+ }
+
+ private void restoreMessages(Conversation conversation) {
+ conversation.addAll(0, databaseBackend.getMessages(conversation, Config.PAGE_SIZE));
+ conversation.findUnsentTextMessages(message -> markMessage(message, Message.STATUS_WAITING));
+ conversation.findUnreadMessages(message -> mNotificationService.pushFromBacklog(message));
+ }
+
+ public void loadPhoneContacts() {
mContactMergerExecutor.execute(() -> {
Map<Jid, JabberIdContact> contacts = JabberIdContact.load(this);
Log.d(Config.LOGTAG, "start merging phone contacts with roster");
@@ -1820,26 +1819,26 @@ public class XmppConnectionService extends Service {
updateRosterUi();
mQuickConversationsService.considerSync();
});
- }
+ }
- public void syncRoster(final Account account) {
- mRosterSyncTaskManager.execute(account, () -> databaseBackend.writeRoster(account.getRoster()));
- }
+ public void syncRoster(final Account account) {
+ mRosterSyncTaskManager.execute(account, () -> databaseBackend.writeRoster(account.getRoster()));
+ }
- public List<Conversation> getConversations() {
- return this.conversations;
- }
+ public List<Conversation> getConversations() {
+ return this.conversations;
+ }
- private void markFileDeleted(final String path) {
+ private void markFileDeleted(final String path) {
final File file = new File(path);
final boolean isInternalFile = fileBackend.isInternalFile(file);
final List<String> uuids = databaseBackend.markFileAsDeleted(file, isInternalFile);
- Log.d(Config.LOGTAG, "deleted file " + path+" internal="+isInternalFile+", database hits="+uuids.size());
+ Log.d(Config.LOGTAG, "deleted file " + path + " internal=" + isInternalFile + ", database hits=" + uuids.size());
markUuidsAsDeletedFiles(uuids);
- }
+ }
- private void markUuidsAsDeletedFiles(List<String> uuids) {
+ private void markUuidsAsDeletedFiles(List<String> uuids) {
boolean deleted = false;
for (Conversation conversation : getConversations()) {
deleted |= conversation.markAsDeleted(uuids);
@@ -1859,37 +1858,37 @@ public class XmppConnectionService extends Service {
}
}
- public void populateWithOrderedConversations(final List<Conversation> list) {
- populateWithOrderedConversations(list, true, true);
- }
+ public void populateWithOrderedConversations(final List<Conversation> list) {
+ populateWithOrderedConversations(list, true, true);
+ }
- public void populateWithOrderedConversations(final List<Conversation> list, final boolean includeNoFileUpload) {
+ public void populateWithOrderedConversations(final List<Conversation> list, final boolean includeNoFileUpload) {
populateWithOrderedConversations(list, includeNoFileUpload, true);
}
- public void populateWithOrderedConversations(final List<Conversation> list, final boolean includeNoFileUpload, final boolean sort) {
+ public void populateWithOrderedConversations(final List<Conversation> list, final boolean includeNoFileUpload, final boolean sort) {
final List<String> orderedUuids;
if (sort) {
orderedUuids = null;
} else {
orderedUuids = new ArrayList<>();
- for(Conversation conversation : list) {
+ for (Conversation conversation : list) {
orderedUuids.add(conversation.getUuid());
}
}
- list.clear();
- if (includeNoFileUpload) {
- list.addAll(getConversations());
- } else {
- for (Conversation conversation : getConversations()) {
- if (conversation.getMode() == Conversation.MODE_SINGLE
- || (conversation.getAccount().httpUploadAvailable() && conversation.getMucOptions().participating())) {
- list.add(conversation);
- }
- }
- }
- try {
- if (orderedUuids != null) {
+ list.clear();
+ if (includeNoFileUpload) {
+ list.addAll(getConversations());
+ } else {
+ for (Conversation conversation : getConversations()) {
+ if (conversation.getMode() == Conversation.MODE_SINGLE
+ || (conversation.getAccount().httpUploadAvailable() && conversation.getMucOptions().participating())) {
+ list.add(conversation);
+ }
+ }
+ }
+ try {
+ if (orderedUuids != null) {
Collections.sort(list, (a, b) -> {
final int indexA = orderedUuids.indexOf(a.getUuid());
final int indexB = orderedUuids.indexOf(b.getUuid());
@@ -1901,361 +1900,361 @@ public class XmppConnectionService extends Service {
} else {
Collections.sort(list);
}
- } catch (IllegalArgumentException e) {
- //ignore
- }
- }
-
- public void loadMoreMessages(final Conversation conversation, final long timestamp, final OnMoreMessagesLoaded callback) {
- if (XmppConnectionService.this.getMessageArchiveService().queryInProgress(conversation, callback)) {
- return;
- } else if (timestamp == 0) {
- return;
- }
- Log.d(Config.LOGTAG, "load more messages for " + conversation.getName() + " prior to " + MessageGenerator.getTimestamp(timestamp));
- final Runnable runnable = () -> {
- final Account account = conversation.getAccount();
- List<Message> messages = databaseBackend.getMessages(conversation, 50, timestamp);
- if (messages.size() > 0) {
- conversation.addAll(0, messages);
- callback.onMoreMessagesLoaded(messages.size(), conversation);
- } else if (conversation.hasMessagesLeftOnServer()
- && account.isOnlineAndConnected()
- && conversation.getLastClearHistory().getTimestamp() == 0) {
- final boolean mamAvailable;
- if (conversation.getMode() == Conversation.MODE_SINGLE) {
- mamAvailable = account.getXmppConnection().getFeatures().mam() && !conversation.getContact().isBlocked();
- } else {
- mamAvailable = conversation.getMucOptions().mamSupport();
- }
- if (mamAvailable) {
- MessageArchiveService.Query query = getMessageArchiveService().query(conversation, new MamReference(0), timestamp, false);
- if (query != null) {
- query.setCallback(callback);
- callback.informUser(R.string.fetching_history_from_server);
- } else {
- callback.informUser(R.string.not_fetching_history_retention_period);
- }
-
- }
- }
- };
- mDatabaseReaderExecutor.execute(runnable);
- }
-
- public List<Account> getAccounts() {
- return this.accounts;
- }
+ } catch (IllegalArgumentException e) {
+ //ignore
+ }
+ }
+
+ public void loadMoreMessages(final Conversation conversation, final long timestamp, final OnMoreMessagesLoaded callback) {
+ if (XmppConnectionService.this.getMessageArchiveService().queryInProgress(conversation, callback)) {
+ return;
+ } else if (timestamp == 0) {
+ return;
+ }
+ Log.d(Config.LOGTAG, "load more messages for " + conversation.getName() + " prior to " + MessageGenerator.getTimestamp(timestamp));
+ final Runnable runnable = () -> {
+ final Account account = conversation.getAccount();
+ List<Message> messages = databaseBackend.getMessages(conversation, 50, timestamp);
+ if (messages.size() > 0) {
+ conversation.addAll(0, messages);
+ callback.onMoreMessagesLoaded(messages.size(), conversation);
+ } else if (conversation.hasMessagesLeftOnServer()
+ && account.isOnlineAndConnected()
+ && conversation.getLastClearHistory().getTimestamp() == 0) {
+ final boolean mamAvailable;
+ if (conversation.getMode() == Conversation.MODE_SINGLE) {
+ mamAvailable = account.getXmppConnection().getFeatures().mam() && !conversation.getContact().isBlocked();
+ } else {
+ mamAvailable = conversation.getMucOptions().mamSupport();
+ }
+ if (mamAvailable) {
+ MessageArchiveService.Query query = getMessageArchiveService().query(conversation, new MamReference(0), timestamp, false);
+ if (query != null) {
+ query.setCallback(callback);
+ callback.informUser(R.string.fetching_history_from_server);
+ } else {
+ callback.informUser(R.string.not_fetching_history_retention_period);
+ }
+
+ }
+ }
+ };
+ mDatabaseReaderExecutor.execute(runnable);
+ }
+
+ public List<Account> getAccounts() {
+ return this.accounts;
+ }
/**
* This will find all conferences with the contact as member and also the conference that is the contact (that 'fake' contact is used to store the avatar)
*/
- public List<Conversation> findAllConferencesWith(Contact contact) {
- ArrayList<Conversation> results = new ArrayList<>();
- for (final Conversation c : conversations) {
- if (c.getMode() == Conversation.MODE_MULTI && (c.getJid().asBareJid().equals(contact.getJid().asBareJid()) || c.getMucOptions().isContactInRoom(contact))) {
- results.add(c);
- }
- }
- return results;
- }
-
- public Conversation find(final Iterable<Conversation> haystack, final Contact contact) {
- for (final Conversation conversation : haystack) {
- if (conversation.getContact() == contact) {
- return conversation;
- }
- }
- return null;
- }
-
- public Conversation find(final Iterable<Conversation> haystack, final Account account, final Jid jid) {
- if (jid == null) {
- return null;
- }
- for (final Conversation conversation : haystack) {
- if ((account == null || conversation.getAccount() == account)
- && (conversation.getJid().asBareJid().equals(jid.asBareJid()))) {
- return conversation;
- }
- }
- return null;
- }
-
- public boolean isConversationsListEmpty(final Conversation ignore) {
- synchronized (this.conversations) {
- final int size = this.conversations.size();
- return size == 0 || size == 1 && this.conversations.get(0) == ignore;
- }
- }
-
- public boolean isConversationStillOpen(final Conversation conversation) {
- synchronized (this.conversations) {
- for (Conversation current : this.conversations) {
- if (current == conversation) {
- return true;
- }
- }
- }
- return false;
- }
-
- public Conversation findOrCreateConversation(Account account, Jid jid, boolean muc, final boolean async) {
- return this.findOrCreateConversation(account, jid, muc, false, async);
- }
-
- public Conversation findOrCreateConversation(final Account account, final Jid jid, final boolean muc, final boolean joinAfterCreate, final boolean async) {
- return this.findOrCreateConversation(account, jid, muc, joinAfterCreate, null, async);
- }
-
- public Conversation findOrCreateConversation(final Account account, final Jid jid, final boolean muc, final boolean joinAfterCreate, final MessageArchiveService.Query query, final boolean async) {
- synchronized (this.conversations) {
- Conversation conversation = find(account, jid);
- if (conversation != null) {
- return conversation;
- }
- conversation = databaseBackend.findConversation(account, jid);
- final boolean loadMessagesFromDb;
- if (conversation != null) {
- conversation.setStatus(Conversation.STATUS_AVAILABLE);
- conversation.setAccount(account);
- if (muc) {
- conversation.setMode(Conversation.MODE_MULTI);
- conversation.setContactJid(jid);
- } else {
- conversation.setMode(Conversation.MODE_SINGLE);
- conversation.setContactJid(jid.asBareJid());
- }
- databaseBackend.updateConversation(conversation);
- loadMessagesFromDb = conversation.messagesLoaded.compareAndSet(true, false);
- } else {
- String conversationName;
- Contact contact = account.getRoster().getContact(jid);
- if (contact != null) {
- conversationName = contact.getDisplayName();
- } else {
- conversationName = jid.getLocal();
- }
- if (muc) {
- conversation = new Conversation(conversationName, account, jid,
- Conversation.MODE_MULTI);
- } else {
- conversation = new Conversation(conversationName, account, jid.asBareJid(),
- Conversation.MODE_SINGLE);
- }
- this.databaseBackend.createConversation(conversation);
- loadMessagesFromDb = false;
- }
- final Conversation c = conversation;
- final Runnable runnable = () -> {
- if (loadMessagesFromDb) {
- c.addAll(0, databaseBackend.getMessages(c, Config.PAGE_SIZE));
- updateConversationUi();
- c.messagesLoaded.set(true);
- }
- if (account.getXmppConnection() != null
- && !c.getContact().isBlocked()
- && account.getXmppConnection().getFeatures().mam()
- && !muc) {
- if (query == null) {
- mMessageArchiveService.query(c);
- } else {
- if (query.getConversation() == null) {
- mMessageArchiveService.query(c, query.getStart(), query.isCatchup());
- }
- }
- }
- if (joinAfterCreate) {
- joinMuc(c);
- }
- };
- if (async) {
- mDatabaseReaderExecutor.execute(runnable);
- } else {
- runnable.run();
- }
- this.conversations.add(conversation);
- updateConversationUi();
- return conversation;
- }
- }
-
- public void archiveConversation(Conversation conversation) {
- archiveConversation(conversation, true);
- }
-
- private void archiveConversation(Conversation conversation, final boolean maySynchronizeWithBookmarks) {
- getNotificationService().clear(conversation);
- conversation.setStatus(Conversation.STATUS_ARCHIVED);
- conversation.setNextMessage(null);
- synchronized (this.conversations) {
- getMessageArchiveService().kill(conversation);
- if (conversation.getMode() == Conversation.MODE_MULTI) {
- if (conversation.getAccount().getStatus() == Account.State.ONLINE) {
- final Bookmark bookmark = conversation.getBookmark();
- if (maySynchronizeWithBookmarks && bookmark != null && synchronizeWithBookmarks()) {
- if (conversation.getMucOptions().getError() == MucOptions.Error.DESTROYED) {
- Account account = bookmark.getAccount();
- bookmark.setConversation(null);
- deleteBookmark(account, bookmark);
- } else if (bookmark.autojoin()) {
- bookmark.setAutojoin(false);
- createBookmark(bookmark.getAccount(), bookmark);
- }
- }
- }
+ public List<Conversation> findAllConferencesWith(Contact contact) {
+ ArrayList<Conversation> results = new ArrayList<>();
+ for (final Conversation c : conversations) {
+ if (c.getMode() == Conversation.MODE_MULTI && (c.getJid().asBareJid().equals(contact.getJid().asBareJid()) || c.getMucOptions().isContactInRoom(contact))) {
+ results.add(c);
+ }
+ }
+ return results;
+ }
+
+ public Conversation find(final Iterable<Conversation> haystack, final Contact contact) {
+ for (final Conversation conversation : haystack) {
+ if (conversation.getContact() == contact) {
+ return conversation;
+ }
+ }
+ return null;
+ }
+
+ public Conversation find(final Iterable<Conversation> haystack, final Account account, final Jid jid) {
+ if (jid == null) {
+ return null;
+ }
+ for (final Conversation conversation : haystack) {
+ if ((account == null || conversation.getAccount() == account)
+ && (conversation.getJid().asBareJid().equals(jid.asBareJid()))) {
+ return conversation;
+ }
+ }
+ return null;
+ }
+
+ public boolean isConversationsListEmpty(final Conversation ignore) {
+ synchronized (this.conversations) {
+ final int size = this.conversations.size();
+ return size == 0 || size == 1 && this.conversations.get(0) == ignore;
+ }
+ }
+
+ public boolean isConversationStillOpen(final Conversation conversation) {
+ synchronized (this.conversations) {
+ for (Conversation current : this.conversations) {
+ if (current == conversation) {
+ return true;
+ }
+ }
+ }
+ return false;
+ }
+
+ public Conversation findOrCreateConversation(Account account, Jid jid, boolean muc, final boolean async) {
+ return this.findOrCreateConversation(account, jid, muc, false, async);
+ }
+
+ public Conversation findOrCreateConversation(final Account account, final Jid jid, final boolean muc, final boolean joinAfterCreate, final boolean async) {
+ return this.findOrCreateConversation(account, jid, muc, joinAfterCreate, null, async);
+ }
+
+ public Conversation findOrCreateConversation(final Account account, final Jid jid, final boolean muc, final boolean joinAfterCreate, final MessageArchiveService.Query query, final boolean async) {
+ synchronized (this.conversations) {
+ Conversation conversation = find(account, jid);
+ if (conversation != null) {
+ return conversation;
+ }
+ conversation = databaseBackend.findConversation(account, jid);
+ final boolean loadMessagesFromDb;
+ if (conversation != null) {
+ conversation.setStatus(Conversation.STATUS_AVAILABLE);
+ conversation.setAccount(account);
+ if (muc) {
+ conversation.setMode(Conversation.MODE_MULTI);
+ conversation.setContactJid(jid);
+ } else {
+ conversation.setMode(Conversation.MODE_SINGLE);
+ conversation.setContactJid(jid.asBareJid());
+ }
+ databaseBackend.updateConversation(conversation);
+ loadMessagesFromDb = conversation.messagesLoaded.compareAndSet(true, false);
+ } else {
+ String conversationName;
+ Contact contact = account.getRoster().getContact(jid);
+ if (contact != null) {
+ conversationName = contact.getDisplayName();
+ } else {
+ conversationName = jid.getLocal();
+ }
+ if (muc) {
+ conversation = new Conversation(conversationName, account, jid,
+ Conversation.MODE_MULTI);
+ } else {
+ conversation = new Conversation(conversationName, account, jid.asBareJid(),
+ Conversation.MODE_SINGLE);
+ }
+ this.databaseBackend.createConversation(conversation);
+ loadMessagesFromDb = false;
+ }
+ final Conversation c = conversation;
+ final Runnable runnable = () -> {
+ if (loadMessagesFromDb) {
+ c.addAll(0, databaseBackend.getMessages(c, Config.PAGE_SIZE));
+ updateConversationUi();
+ c.messagesLoaded.set(true);
+ }
+ if (account.getXmppConnection() != null
+ && !c.getContact().isBlocked()
+ && account.getXmppConnection().getFeatures().mam()
+ && !muc) {
+ if (query == null) {
+ mMessageArchiveService.query(c);
+ } else {
+ if (query.getConversation() == null) {
+ mMessageArchiveService.query(c, query.getStart(), query.isCatchup());
+ }
+ }
+ }
+ if (joinAfterCreate) {
+ joinMuc(c);
+ }
+ };
+ if (async) {
+ mDatabaseReaderExecutor.execute(runnable);
+ } else {
+ runnable.run();
+ }
+ this.conversations.add(conversation);
+ updateConversationUi();
+ return conversation;
+ }
+ }
+
+ public void archiveConversation(Conversation conversation) {
+ archiveConversation(conversation, true);
+ }
+
+ private void archiveConversation(Conversation conversation, final boolean maySynchronizeWithBookmarks) {
+ getNotificationService().clear(conversation);
+ conversation.setStatus(Conversation.STATUS_ARCHIVED);
+ conversation.setNextMessage(null);
+ synchronized (this.conversations) {
+ getMessageArchiveService().kill(conversation);
+ if (conversation.getMode() == Conversation.MODE_MULTI) {
+ if (conversation.getAccount().getStatus() == Account.State.ONLINE) {
+ final Bookmark bookmark = conversation.getBookmark();
+ if (maySynchronizeWithBookmarks && bookmark != null && synchronizeWithBookmarks()) {
+ if (conversation.getMucOptions().getError() == MucOptions.Error.DESTROYED) {
+ Account account = bookmark.getAccount();
+ bookmark.setConversation(null);
+ deleteBookmark(account, bookmark);
+ } else if (bookmark.autojoin()) {
+ bookmark.setAutojoin(false);
+ createBookmark(bookmark.getAccount(), bookmark);
+ }
+ }
+ }
if (conversation.getMucOptions().push()) {
disableDirectMucPush(conversation);
mPushManagementService.disablePushOnServer(conversation);
}
- leaveMuc(conversation);
- } else {
- if (conversation.getContact().getOption(Contact.Options.PENDING_SUBSCRIPTION_REQUEST)) {
- stopPresenceUpdatesTo(conversation.getContact());
- }
- }
- updateConversation(conversation);
- this.conversations.remove(conversation);
- updateConversationUi();
- }
- }
-
- public void stopPresenceUpdatesTo(Contact contact) {
+ leaveMuc(conversation);
+ } else {
+ if (conversation.getContact().getOption(Contact.Options.PENDING_SUBSCRIPTION_REQUEST)) {
+ stopPresenceUpdatesTo(conversation.getContact());
+ }
+ }
+ updateConversation(conversation);
+ this.conversations.remove(conversation);
+ updateConversationUi();
+ }
+ }
+
+ public void stopPresenceUpdatesTo(Contact contact) {
Log.d(Config.LOGTAG, "Canceling presence request from " + contact.getJid().toString());
sendPresencePacket(contact.getAccount(), mPresenceGenerator.stopPresenceUpdatesTo(contact));
contact.resetOption(Contact.Options.PENDING_SUBSCRIPTION_REQUEST);
}
- public void createAccount(final Account account) {
- account.initAccountServices(this);
- databaseBackend.createAccount(account);
- this.accounts.add(account);
- this.reconnectAccountInBackground(account);
- updateAccountUi();
- syncEnabledAccountSetting();
- toggleForegroundService();
- }
-
- private void syncEnabledAccountSetting() {
- final boolean hasEnabledAccounts = hasEnabledAccounts();
- getPreferences().edit().putBoolean(EventReceiver.SETTING_ENABLED_ACCOUNTS, hasEnabledAccounts).apply();
- toggleSetProfilePictureActivity(hasEnabledAccounts);
- }
-
- private void toggleSetProfilePictureActivity(final boolean enabled) {
- try {
- final ComponentName name = new ComponentName(this, ChooseAccountForProfilePictureActivity.class);
- final int targetState = enabled ? PackageManager.COMPONENT_ENABLED_STATE_ENABLED : PackageManager.COMPONENT_ENABLED_STATE_DISABLED;
+ public void createAccount(final Account account) {
+ account.initAccountServices(this);
+ databaseBackend.createAccount(account);
+ this.accounts.add(account);
+ this.reconnectAccountInBackground(account);
+ updateAccountUi();
+ syncEnabledAccountSetting();
+ toggleForegroundService();
+ }
+
+ private void syncEnabledAccountSetting() {
+ final boolean hasEnabledAccounts = hasEnabledAccounts();
+ getPreferences().edit().putBoolean(EventReceiver.SETTING_ENABLED_ACCOUNTS, hasEnabledAccounts).apply();
+ toggleSetProfilePictureActivity(hasEnabledAccounts);
+ }
+
+ private void toggleSetProfilePictureActivity(final boolean enabled) {
+ try {
+ final ComponentName name = new ComponentName(this, ChooseAccountForProfilePictureActivity.class);
+ final int targetState = enabled ? PackageManager.COMPONENT_ENABLED_STATE_ENABLED : PackageManager.COMPONENT_ENABLED_STATE_DISABLED;
getPackageManager().setComponentEnabledSetting(name, targetState, PackageManager.DONT_KILL_APP);
} catch (IllegalStateException e) {
- Log.d(Config.LOGTAG,"unable to toggle profile picture actvitiy");
- }
- }
-
- public void createAccountFromKey(final String alias, final OnAccountCreated callback) {
- new Thread(() -> {
- try {
- final X509Certificate[] chain = KeyChain.getCertificateChain(this, alias);
- final X509Certificate cert = chain != null && chain.length > 0 ? chain[0] : null;
- if (cert == null) {
- callback.informUser(R.string.unable_to_parse_certificate);
- return;
- }
- Pair<Jid, String> info = CryptoHelper.extractJidAndName(cert);
- if (info == null) {
- callback.informUser(R.string.certificate_does_not_contain_jid);
- return;
- }
- if (findAccountByJid(info.first) == null) {
- Account account = new Account(info.first, "");
- account.setPrivateKeyAlias(alias);
- account.setOption(Account.OPTION_DISABLED, true);
- account.setDisplayName(info.second);
- createAccount(account);
- callback.onAccountCreated(account);
- if (Config.X509_VERIFICATION) {
- try {
- getMemorizingTrustManager().getNonInteractive(account.getJid().getDomain()).checkClientTrusted(chain, "RSA");
- } catch (CertificateException e) {
- callback.informUser(R.string.certificate_chain_is_not_trusted);
- }
- }
- } else {
- callback.informUser(R.string.account_already_exists);
- }
- } catch (Exception e) {
- e.printStackTrace();
- callback.informUser(R.string.unable_to_parse_certificate);
- }
- }).start();
-
- }
-
- public void updateKeyInAccount(final Account account, final String alias) {
- Log.d(Config.LOGTAG, account.getJid().asBareJid() + ": update key in account " + alias);
- try {
- X509Certificate[] chain = KeyChain.getCertificateChain(XmppConnectionService.this, alias);
- Log.d(Config.LOGTAG, account.getJid().asBareJid() + " loaded certificate chain");
- Pair<Jid, String> info = CryptoHelper.extractJidAndName(chain[0]);
- if (info == null) {
- showErrorToastInUi(R.string.certificate_does_not_contain_jid);
- return;
- }
- if (account.getJid().asBareJid().equals(info.first)) {
- account.setPrivateKeyAlias(alias);
- account.setDisplayName(info.second);
- databaseBackend.updateAccount(account);
- if (Config.X509_VERIFICATION) {
- try {
- getMemorizingTrustManager().getNonInteractive().checkClientTrusted(chain, "RSA");
- } catch (CertificateException e) {
- showErrorToastInUi(R.string.certificate_chain_is_not_trusted);
- }
- account.getAxolotlService().regenerateKeys(true);
- }
- } else {
- showErrorToastInUi(R.string.jid_does_not_match_certificate);
- }
- } catch (Exception e) {
- e.printStackTrace();
- }
- }
-
- public boolean updateAccount(final Account account) {
- if (databaseBackend.updateAccount(account)) {
- account.setShowErrorNotification(true);
- this.statusListener.onStatusChanged(account);
- databaseBackend.updateAccount(account);
- reconnectAccountInBackground(account);
- updateAccountUi();
- getNotificationService().updateErrorNotification();
- toggleForegroundService();
- syncEnabledAccountSetting();
- return true;
- } else {
- return false;
- }
- }
-
- public void updateAccountPasswordOnServer(final Account account, final String newPassword, final OnAccountPasswordChanged callback) {
- final IqPacket iq = getIqGenerator().generateSetPassword(account, newPassword);
- sendIqPacket(account, iq, (a, packet) -> {
- if (packet.getType() == IqPacket.TYPE.RESULT) {
- a.setPassword(newPassword);
- a.setOption(Account.OPTION_MAGIC_CREATE, false);
- databaseBackend.updateAccount(a);
- callback.onPasswordChangeSucceeded();
- } else {
- callback.onPasswordChangeFailed();
- }
- });
- }
-
- public void deleteAccount(final Account account) {
- final boolean connected = account.getStatus() == Account.State.ONLINE;
- synchronized (this.conversations) {
- if (connected) {
+ Log.d(Config.LOGTAG, "unable to toggle profile picture actvitiy");
+ }
+ }
+
+ public void createAccountFromKey(final String alias, final OnAccountCreated callback) {
+ new Thread(() -> {
+ try {
+ final X509Certificate[] chain = KeyChain.getCertificateChain(this, alias);
+ final X509Certificate cert = chain != null && chain.length > 0 ? chain[0] : null;
+ if (cert == null) {
+ callback.informUser(R.string.unable_to_parse_certificate);
+ return;
+ }
+ Pair<Jid, String> info = CryptoHelper.extractJidAndName(cert);
+ if (info == null) {
+ callback.informUser(R.string.certificate_does_not_contain_jid);
+ return;
+ }
+ if (findAccountByJid(info.first) == null) {
+ Account account = new Account(info.first, "");
+ account.setPrivateKeyAlias(alias);
+ account.setOption(Account.OPTION_DISABLED, true);
+ account.setDisplayName(info.second);
+ createAccount(account);
+ callback.onAccountCreated(account);
+ if (Config.X509_VERIFICATION) {
+ try {
+ getMemorizingTrustManager().getNonInteractive(account.getJid().getDomain()).checkClientTrusted(chain, "RSA");
+ } catch (CertificateException e) {
+ callback.informUser(R.string.certificate_chain_is_not_trusted);
+ }
+ }
+ } else {
+ callback.informUser(R.string.account_already_exists);
+ }
+ } catch (Exception e) {
+ e.printStackTrace();
+ callback.informUser(R.string.unable_to_parse_certificate);
+ }
+ }).start();
+
+ }
+
+ public void updateKeyInAccount(final Account account, final String alias) {
+ Log.d(Config.LOGTAG, account.getJid().asBareJid() + ": update key in account " + alias);
+ try {
+ X509Certificate[] chain = KeyChain.getCertificateChain(XmppConnectionService.this, alias);
+ Log.d(Config.LOGTAG, account.getJid().asBareJid() + " loaded certificate chain");
+ Pair<Jid, String> info = CryptoHelper.extractJidAndName(chain[0]);
+ if (info == null) {
+ showErrorToastInUi(R.string.certificate_does_not_contain_jid);
+ return;
+ }
+ if (account.getJid().asBareJid().equals(info.first)) {
+ account.setPrivateKeyAlias(alias);
+ account.setDisplayName(info.second);
+ databaseBackend.updateAccount(account);
+ if (Config.X509_VERIFICATION) {
+ try {
+ getMemorizingTrustManager().getNonInteractive().checkClientTrusted(chain, "RSA");
+ } catch (CertificateException e) {
+ showErrorToastInUi(R.string.certificate_chain_is_not_trusted);
+ }
+ account.getAxolotlService().regenerateKeys(true);
+ }
+ } else {
+ showErrorToastInUi(R.string.jid_does_not_match_certificate);
+ }
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ }
+
+ public boolean updateAccount(final Account account) {
+ if (databaseBackend.updateAccount(account)) {
+ account.setShowErrorNotification(true);
+ this.statusListener.onStatusChanged(account);
+ databaseBackend.updateAccount(account);
+ reconnectAccountInBackground(account);
+ updateAccountUi();
+ getNotificationService().updateErrorNotification();
+ toggleForegroundService();
+ syncEnabledAccountSetting();
+ return true;
+ } else {
+ return false;
+ }
+ }
+
+ public void updateAccountPasswordOnServer(final Account account, final String newPassword, final OnAccountPasswordChanged callback) {
+ final IqPacket iq = getIqGenerator().generateSetPassword(account, newPassword);
+ sendIqPacket(account, iq, (a, packet) -> {
+ if (packet.getType() == IqPacket.TYPE.RESULT) {
+ a.setPassword(newPassword);
+ a.setOption(Account.OPTION_MAGIC_CREATE, false);
+ databaseBackend.updateAccount(a);
+ callback.onPasswordChangeSucceeded();
+ } else {
+ callback.onPasswordChangeFailed();
+ }
+ });
+ }
+
+ public void deleteAccount(final Account account) {
+ final boolean connected = account.getStatus() == Account.State.ONLINE;
+ synchronized (this.conversations) {
+ if (connected) {
account.getAxolotlService().deleteOmemoIdentity();
}
for (final Conversation conversation : conversations) {