Resync has_enabled_account setting after delete and on start

This commit is contained in:
Daniel Gultsch 2017-10-28 17:49:51 +02:00
parent 3205d763cf
commit 8f0cd86090

View file

@ -282,7 +282,7 @@ public class XmppConnectionService extends Service {
private int keyStatusUpdatedListenerCount = 0; private int keyStatusUpdatedListenerCount = 0;
private AtomicLong mLastExpiryRun = new AtomicLong(0); private AtomicLong mLastExpiryRun = new AtomicLong(0);
private SecureRandom mRandom; private SecureRandom mRandom;
private LruCache<Pair<String,String>,ServiceDiscoveryResult> discoCache = new LruCache<>(20); private LruCache<Pair<String, String>, ServiceDiscoveryResult> discoCache = new LruCache<>(20);
private final OnBindListener mOnBindListener = new OnBindListener() { private final OnBindListener mOnBindListener = new OnBindListener() {
@Override @Override
@ -295,7 +295,7 @@ public class XmppConnectionService extends Service {
} }
} }
} }
if (account.setOption(Account.OPTION_LOGGED_IN_SUCCESSFULLY,true)) { if (account.setOption(Account.OPTION_LOGGED_IN_SUCCESSFULLY, true)) {
databaseBackend.updateAccount(account); databaseBackend.updateAccount(account);
} }
account.getRoster().clearPresences(); account.getRoster().clearPresences();
@ -342,7 +342,7 @@ public class XmppConnectionService extends Service {
if (conversation.getAccount() == account if (conversation.getAccount() == account
&& !account.pendingConferenceJoins.contains(conversation)) { && !account.pendingConferenceJoins.contains(conversation)) {
if (!conversation.startOtrIfNeeded()) { if (!conversation.startOtrIfNeeded()) {
Log.d(Config.LOGTAG,account.getJid().toBareJid()+": couldn't start OTR with "+conversation.getContact().getJid()+" when needed"); Log.d(Config.LOGTAG, account.getJid().toBareJid() + ": couldn't start OTR with " + conversation.getContact().getJid() + " when needed");
} }
sendUnsentMessages(conversation); sendUnsentMessages(conversation);
} }
@ -374,11 +374,11 @@ public class XmppConnectionService extends Service {
final int next = connection.getTimeToNextAttempt(); final int next = connection.getTimeToNextAttempt();
final boolean lowPingTimeoutMode = isInLowPingTimeoutMode(account); final boolean lowPingTimeoutMode = isInLowPingTimeoutMode(account);
if (next <= 0) { if (next <= 0) {
Log.d(Config.LOGTAG, account.getJid().toBareJid()+": error connecting account. reconnecting now. lowPingTimeout="+Boolean.toString(lowPingTimeoutMode)); Log.d(Config.LOGTAG, account.getJid().toBareJid() + ": error connecting account. reconnecting now. lowPingTimeout=" + Boolean.toString(lowPingTimeoutMode));
reconnectAccount(account, true, false); reconnectAccount(account, true, false);
} else { } else {
final int attempt = connection.getAttempt() + 1; final int attempt = connection.getAttempt() + 1;
Log.d(Config.LOGTAG, account.getJid().toBareJid() + ": error connecting account. try again in " + next + "s for the " + attempt+ " time. lowPingTimeout="+Boolean.toString(lowPingTimeoutMode)); Log.d(Config.LOGTAG, account.getJid().toBareJid() + ": error connecting account. try again in " + next + "s for the " + attempt + " time. lowPingTimeout=" + Boolean.toString(lowPingTimeoutMode));
scheduleWakeUpCall(next, account.getUuid().hashCode()); scheduleWakeUpCall(next, account.getUuid().hashCode());
} }
} }
@ -455,8 +455,8 @@ public class XmppConnectionService extends Service {
} }
public void attachLocationToConversation(final Conversation conversation, public void attachLocationToConversation(final Conversation conversation,
final Uri uri, final Uri uri,
final UiCallback<Message> callback) { final UiCallback<Message> callback) {
int encryption = conversation.getNextEncryption(); int encryption = conversation.getNextEncryption();
if (encryption == Message.ENCRYPTION_PGP) { if (encryption == Message.ENCRYPTION_PGP) {
encryption = Message.ENCRYPTION_DECRYPTED; encryption = Message.ENCRYPTION_DECRYPTED;
@ -473,10 +473,10 @@ public class XmppConnectionService extends Service {
} }
public void attachFileToConversation(final Conversation conversation, public void attachFileToConversation(final Conversation conversation,
final Uri uri, final Uri uri,
final UiCallback<Message> callback) { final UiCallback<Message> callback) {
if (FileBackend.weOwnFile(this, uri)) { if (FileBackend.weOwnFile(this, uri)) {
Log.d(Config.LOGTAG,"trying to attach file that belonged to us"); Log.d(Config.LOGTAG, "trying to attach file that belonged to us");
callback.error(R.string.security_error_invalid_file_access, null); callback.error(R.string.security_error_invalid_file_access, null);
return; return;
} }
@ -488,7 +488,7 @@ public class XmppConnectionService extends Service {
} }
message.setCounterpart(conversation.getNextCounterpart()); message.setCounterpart(conversation.getNextCounterpart());
message.setType(Message.TYPE_FILE); message.setType(Message.TYPE_FILE);
final AttachFileToConversationRunnable runnable = new AttachFileToConversationRunnable(this,uri,message,callback); final AttachFileToConversationRunnable runnable = new AttachFileToConversationRunnable(this, uri, message, callback);
if (runnable.isVideoMessage()) { if (runnable.isVideoMessage()) {
mVideoCompressionExecutor.execute(runnable); mVideoCompressionExecutor.execute(runnable);
} else { } else {
@ -498,7 +498,7 @@ public class XmppConnectionService extends Service {
public void attachImageToConversation(final Conversation conversation, final Uri uri, final UiCallback<Message> callback) { public void attachImageToConversation(final Conversation conversation, final Uri uri, final UiCallback<Message> callback) {
if (FileBackend.weOwnFile(this, uri)) { if (FileBackend.weOwnFile(this, uri)) {
Log.d(Config.LOGTAG,"trying to attach file that belonged to us"); Log.d(Config.LOGTAG, "trying to attach file that belonged to us");
callback.error(R.string.security_error_invalid_file_access, null); callback.error(R.string.security_error_invalid_file_access, null);
return; return;
} }
@ -509,7 +509,7 @@ public class XmppConnectionService extends Service {
if ("never".equals(compressPictures) if ("never".equals(compressPictures)
|| ("auto".equals(compressPictures) && getFileBackend().useImageAsIs(uri)) || ("auto".equals(compressPictures) && getFileBackend().useImageAsIs(uri))
|| (mimeType != null && mimeType.endsWith("/gif"))) { || (mimeType != null && mimeType.endsWith("/gif"))) {
Log.d(Config.LOGTAG,conversation.getAccount().getJid().toBareJid()+ ": not compressing picture. sending as file"); Log.d(Config.LOGTAG, conversation.getAccount().getJid().toBareJid() + ": not compressing picture. sending as file");
attachFileToConversation(conversation, uri, callback); attachFileToConversation(conversation, uri, callback);
return; return;
} }
@ -531,7 +531,7 @@ public class XmppConnectionService extends Service {
final PgpEngine pgpEngine = getPgpEngine(); final PgpEngine pgpEngine = getPgpEngine();
if (pgpEngine != null) { if (pgpEngine != null) {
pgpEngine.encrypt(message, callback); pgpEngine.encrypt(message, callback);
} else if (callback != null){ } else if (callback != null) {
callback.error(R.string.unable_to_connect_to_keychain, null); callback.error(R.string.unable_to_connect_to_keychain, null);
} }
} else { } else {
@ -593,7 +593,7 @@ public class XmppConnectionService extends Service {
if (remoteInput != null && c != null) { if (remoteInput != null && c != null) {
final CharSequence body = remoteInput.getCharSequence("text_reply"); final CharSequence body = remoteInput.getCharSequence("text_reply");
if (body != null && body.length() > 0) { if (body != null && body.length() > 0) {
directReply(c, body.toString(),intent.getBooleanExtra("dismiss_notification",false)); directReply(c, body.toString(), intent.getBooleanExtra("dismiss_notification", false));
} }
} }
break; break;
@ -601,7 +601,7 @@ public class XmppConnectionService extends Service {
if (c != null) { if (c != null) {
sendReadMarker(c); sendReadMarker(c);
} else { } else {
Log.d(Config.LOGTAG,"received mark read intent for unknown conversation ("+uuid+")"); Log.d(Config.LOGTAG, "received mark read intent for unknown conversation (" + uuid + ")");
} }
break; break;
case AudioManager.RINGER_MODE_CHANGED_ACTION: case AudioManager.RINGER_MODE_CHANGED_ACTION:
@ -625,7 +625,7 @@ public class XmppConnectionService extends Service {
} }
break; break;
case ACTION_GCM_MESSAGE_RECEIVED: case ACTION_GCM_MESSAGE_RECEIVED:
Log.d(Config.LOGTAG,"gcm push message arrived in service. extras="+intent.getExtras()); Log.d(Config.LOGTAG, "gcm push message arrived in service. extras=" + intent.getExtras());
pushedAccountHash = intent.getStringExtra("account"); pushedAccountHash = intent.getStringExtra("account");
break; break;
} }
@ -718,14 +718,14 @@ public class XmppConnectionService extends Service {
long discoTimeout = Config.CONNECT_DISCO_TIMEOUT - secondsSinceLastDisco; long discoTimeout = Config.CONNECT_DISCO_TIMEOUT - secondsSinceLastDisco;
long timeout = Config.CONNECT_TIMEOUT - secondsSinceLastConnect; long timeout = Config.CONNECT_TIMEOUT - secondsSinceLastConnect;
if (timeout < 0) { if (timeout < 0) {
Log.d(Config.LOGTAG, account.getJid() + ": time out during connect reconnecting (secondsSinceLast="+secondsSinceLastConnect+")"); Log.d(Config.LOGTAG, account.getJid() + ": time out during connect reconnecting (secondsSinceLast=" + secondsSinceLastConnect + ")");
account.getXmppConnection().resetAttemptCount(false); account.getXmppConnection().resetAttemptCount(false);
reconnectAccount(account, true, interactive); reconnectAccount(account, true, interactive);
} else if (discoTimeout < 0) { } else if (discoTimeout < 0) {
account.getXmppConnection().sendDiscoTimeout(); account.getXmppConnection().sendDiscoTimeout();
scheduleWakeUpCall((int) Math.min(timeout,discoTimeout), account.getUuid().hashCode()); scheduleWakeUpCall((int) Math.min(timeout, discoTimeout), account.getUuid().hashCode());
} else { } else {
scheduleWakeUpCall((int) Math.min(timeout,discoTimeout), account.getUuid().hashCode()); scheduleWakeUpCall((int) Math.min(timeout, discoTimeout), account.getUuid().hashCode());
} }
} else { } else {
if (account.getXmppConnection().getTimeToNextAttempt() <= 0) { if (account.getXmppConnection().getTimeToNextAttempt() <= 0) {
@ -748,7 +748,7 @@ public class XmppConnectionService extends Service {
} }
private void directReply(Conversation conversation, String body, final boolean dismissAfterReply) { private void directReply(Conversation conversation, String body, final boolean dismissAfterReply) {
Message message = new Message(conversation,body,conversation.getNextEncryption()); Message message = new Message(conversation, body, conversation.getNextEncryption());
message.markUnread(); message.markUnread();
if (message.getEncryption() == Message.ENCRYPTION_PGP) { if (message.getEncryption() == Message.ENCRYPTION_PGP) {
getPgpEngine().encrypt(message, new UiCallback<Message>() { getPgpEngine().encrypt(message, new UiCallback<Message>() {
@ -757,7 +757,7 @@ public class XmppConnectionService extends Service {
message.setEncryption(Message.ENCRYPTION_DECRYPTED); message.setEncryption(Message.ENCRYPTION_DECRYPTED);
sendMessage(message); sendMessage(message);
if (dismissAfterReply) { if (dismissAfterReply) {
markRead(message.getConversation(),true); markRead(message.getConversation(), true);
} else { } else {
mNotificationService.pushFromDirectReply(message); mNotificationService.pushFromDirectReply(message);
} }
@ -776,7 +776,7 @@ public class XmppConnectionService extends Service {
} else { } else {
sendMessage(message); sendMessage(message);
if (dismissAfterReply) { if (dismissAfterReply) {
markRead(conversation,true); markRead(conversation, true);
} else { } else {
mNotificationService.pushFromDirectReply(message); mNotificationService.pushFromDirectReply(message);
} }
@ -796,7 +796,7 @@ public class XmppConnectionService extends Service {
} }
private boolean awayWhenScreenOff() { private boolean awayWhenScreenOff() {
return getBooleanPreference(SettingsActivity.AWAY_WHEN_SCREEN_IS_OFF,R.bool.away_when_screen_off); return getBooleanPreference(SettingsActivity.AWAY_WHEN_SCREEN_IS_OFF, R.bool.away_when_screen_off);
} }
private String getCompressPicturesPreference() { private String getCompressPicturesPreference() {
@ -836,7 +836,7 @@ public class XmppConnectionService extends Service {
return audioManager.getRingerMode() == AudioManager.RINGER_MODE_SILENT; return audioManager.getRingerMode() == AudioManager.RINGER_MODE_SILENT;
} }
} catch (Throwable throwable) { } catch (Throwable throwable) {
Log.d(Config.LOGTAG,"platform bug in isPhoneSilenced ("+ throwable.getMessage()+")"); Log.d(Config.LOGTAG, "platform bug in isPhoneSilenced (" + throwable.getMessage() + ")");
return false; return false;
} }
} }
@ -860,7 +860,7 @@ public class XmppConnectionService extends Service {
private void dismissErrorNotifications() { private void dismissErrorNotifications() {
for (final Account account : this.accounts) { for (final Account account : this.accounts) {
if (account.hasErrorStatus()) { if (account.hasErrorStatus()) {
Log.d(Config.LOGTAG,account.getJid().toBareJid()+": dismissing error notification"); Log.d(Config.LOGTAG, account.getJid().toBareJid() + ": dismissing error notification");
if (account.setShowErrorNotification(false)) { if (account.setShowErrorNotification(false)) {
databaseBackend.updateAccount(account); databaseBackend.updateAccount(account);
} }
@ -919,15 +919,17 @@ public class XmppConnectionService extends Service {
} }
}; };
Log.d(Config.LOGTAG,"initializing database..."); Log.d(Config.LOGTAG, "initializing database...");
this.databaseBackend = DatabaseBackend.getInstance(getApplicationContext()); this.databaseBackend = DatabaseBackend.getInstance(getApplicationContext());
Log.d(Config.LOGTAG,"restoring accounts..."); Log.d(Config.LOGTAG, "restoring accounts...");
this.accounts = databaseBackend.getAccounts(); this.accounts = databaseBackend.getAccounts();
final SharedPreferences.Editor editor = getPreferences().edit();
if (this.accounts.size() == 0 && Arrays.asList("Sony","Sony Ericsson").contains(Build.MANUFACTURER)) { if (this.accounts.size() == 0 && Arrays.asList("Sony", "Sony Ericsson").contains(Build.MANUFACTURER)) {
getPreferences().edit().putBoolean(SettingsActivity.KEEP_FOREGROUND_SERVICE,true).commit(); editor.putBoolean(SettingsActivity.KEEP_FOREGROUND_SERVICE, true);
Log.d(Config.LOGTAG,Build.MANUFACTURER+" is on blacklist. enabling foreground service"); Log.d(Config.LOGTAG, Build.MANUFACTURER + " is on blacklist. enabling foreground service");
} }
editor.putBoolean(EventReceiver.SETTING_ENABLED_ACCOUNTS, hasEnabledAccounts()).apply();
editor.apply();
restoreFromDatabase(); restoreFromDatabase();
@ -939,12 +941,12 @@ public class XmppConnectionService extends Service {
} }
}).start(); }).start();
if (Config.supportOpenPgp()) { if (Config.supportOpenPgp()) {
this.pgpServiceConnection = new OpenPgpServiceConnection(getApplicationContext(), "org.sufficientlysecure.keychain", new OpenPgpServiceConnection.OnBound() { this.pgpServiceConnection = new OpenPgpServiceConnection(this, "org.sufficientlysecure.keychain", new OpenPgpServiceConnection.OnBound() {
@Override @Override
public void onBound(IOpenPgpService2 service) { public void onBound(IOpenPgpService2 service) {
for (Account account : accounts) { for (Account account : accounts) {
final PgpDecryptionService pgp = account.getPgpDecryptionService(); final PgpDecryptionService pgp = account.getPgpDecryptionService();
if(pgp != null) { if (pgp != null) {
pgp.continueDecryption(true); pgp.continueDecryption(true);
} }
} }
@ -967,7 +969,7 @@ public class XmppConnectionService extends Service {
scheduleNextIdlePing(); scheduleNextIdlePing();
} }
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
registerReceiver(this.mEventReceiver,new IntentFilter(ConnectivityManager.CONNECTIVITY_ACTION)); registerReceiver(this.mEventReceiver, new IntentFilter(ConnectivityManager.CONNECTIVITY_ACTION));
} }
} }
@ -1008,22 +1010,22 @@ public class XmppConnectionService extends Service {
public void toggleForegroundService() { public void toggleForegroundService() {
if (mForceForegroundService.get() || (keepForegroundService() && hasEnabledAccounts())) { if (mForceForegroundService.get() || (keepForegroundService() && hasEnabledAccounts())) {
startForeground(NotificationService.FOREGROUND_NOTIFICATION_ID, this.mNotificationService.createForegroundNotification()); startForeground(NotificationService.FOREGROUND_NOTIFICATION_ID, this.mNotificationService.createForegroundNotification());
Log.d(Config.LOGTAG,"started foreground service"); Log.d(Config.LOGTAG, "started foreground service");
} else { } else {
stopForeground(true); stopForeground(true);
Log.d(Config.LOGTAG,"stopped foreground service"); Log.d(Config.LOGTAG, "stopped foreground service");
} }
} }
public boolean keepForegroundService() { public boolean keepForegroundService() {
return getBooleanPreference(SettingsActivity.KEEP_FOREGROUND_SERVICE,R.bool.enable_foreground_service); return getBooleanPreference(SettingsActivity.KEEP_FOREGROUND_SERVICE, R.bool.enable_foreground_service);
} }
@Override @Override
public void onTaskRemoved(final Intent rootIntent) { public void onTaskRemoved(final Intent rootIntent) {
super.onTaskRemoved(rootIntent); super.onTaskRemoved(rootIntent);
if (keepForegroundService() || mForceForegroundService.get()) { if (keepForegroundService() || mForceForegroundService.get()) {
Log.d(Config.LOGTAG,"ignoring onTaskRemoved because foreground service is activated"); Log.d(Config.LOGTAG, "ignoring onTaskRemoved because foreground service is activated");
} else { } else {
this.logoutAndSave(false); this.logoutAndSave(false);
} }
@ -1062,14 +1064,14 @@ public class XmppConnectionService extends Service {
@TargetApi(Build.VERSION_CODES.M) @TargetApi(Build.VERSION_CODES.M)
private void scheduleNextIdlePing() { private void scheduleNextIdlePing() {
Log.d(Config.LOGTAG,"schedule next idle ping"); Log.d(Config.LOGTAG, "schedule next idle ping");
AlarmManager alarmManager = (AlarmManager) getSystemService(Context.ALARM_SERVICE); AlarmManager alarmManager = (AlarmManager) getSystemService(Context.ALARM_SERVICE);
Intent intent = new Intent(this, EventReceiver.class); Intent intent = new Intent(this, EventReceiver.class);
intent.setAction(ACTION_IDLE_PING); intent.setAction(ACTION_IDLE_PING);
alarmManager.setAndAllowWhileIdle(AlarmManager.ELAPSED_REALTIME_WAKEUP, alarmManager.setAndAllowWhileIdle(AlarmManager.ELAPSED_REALTIME_WAKEUP,
SystemClock.elapsedRealtime()+(Config.IDLE_PING_INTERVAL * 1000), SystemClock.elapsedRealtime() + (Config.IDLE_PING_INTERVAL * 1000),
PendingIntent.getBroadcast(this,0,intent,0) PendingIntent.getBroadcast(this, 0, intent, 0)
); );
} }
public XmppConnection createConnection(final Account account) { public XmppConnection createConnection(final Account account) {
@ -1111,7 +1113,7 @@ public class XmppConnectionService extends Service {
private void sendFileMessage(final Message message, final boolean delay) { private void sendFileMessage(final Message message, final boolean delay) {
Log.d(Config.LOGTAG, "send file message"); Log.d(Config.LOGTAG, "send file message");
final Account account = message.getConversation().getAccount(); final Account account = message.getConversation().getAccount();
if (account.httpUploadAvailable(fileBackend.getFile(message,false).getSize()) if (account.httpUploadAvailable(fileBackend.getFile(message, false).getSize())
|| message.getConversation().getMode() == Conversation.MODE_MULTI) { || message.getConversation().getMode() == Conversation.MODE_MULTI) {
mHttpConnectionManager.createNewUploadConnection(message, delay); mHttpConnectionManager.createNewUploadConnection(message, delay);
} else { } else {
@ -1153,7 +1155,7 @@ public class XmppConnectionService extends Service {
switch (message.getEncryption()) { switch (message.getEncryption()) {
case Message.ENCRYPTION_NONE: case Message.ENCRYPTION_NONE:
if (message.needsUploading()) { if (message.needsUploading()) {
if (account.httpUploadAvailable(fileBackend.getFile(message,false).getSize()) if (account.httpUploadAvailable(fileBackend.getFile(message, false).getSize())
|| conversation.getMode() == Conversation.MODE_MULTI || conversation.getMode() == Conversation.MODE_MULTI
|| message.fixCounterpart()) { || message.fixCounterpart()) {
this.sendFileMessage(message, delay); this.sendFileMessage(message, delay);
@ -1167,7 +1169,7 @@ public class XmppConnectionService extends Service {
case Message.ENCRYPTION_PGP: case Message.ENCRYPTION_PGP:
case Message.ENCRYPTION_DECRYPTED: case Message.ENCRYPTION_DECRYPTED:
if (message.needsUploading()) { if (message.needsUploading()) {
if (account.httpUploadAvailable(fileBackend.getFile(message,false).getSize()) if (account.httpUploadAvailable(fileBackend.getFile(message, false).getSize())
|| conversation.getMode() == Conversation.MODE_MULTI || conversation.getMode() == Conversation.MODE_MULTI
|| message.fixCounterpart()) { || message.fixCounterpart()) {
this.sendFileMessage(message, delay); this.sendFileMessage(message, delay);
@ -1195,17 +1197,17 @@ public class XmppConnectionService extends Service {
if (message.fixCounterpart()) { if (message.fixCounterpart()) {
conversation.startOtrSession(message.getCounterpart().getResourcepart(), true); conversation.startOtrSession(message.getCounterpart().getResourcepart(), true);
} else { } else {
Log.d(Config.LOGTAG,account.getJid().toBareJid()+": could not fix counterpart for OTR message to contact "+message.getCounterpart()); Log.d(Config.LOGTAG, account.getJid().toBareJid() + ": could not fix counterpart for OTR message to contact " + message.getCounterpart());
break; break;
} }
} else { } else {
Log.d(Config.LOGTAG,account.getJid().toBareJid()+" OTR session with "+message.getContact()+" is in wrong state: "+otrSession.getSessionStatus().toString()); Log.d(Config.LOGTAG, account.getJid().toBareJid() + " OTR session with " + message.getContact() + " is in wrong state: " + otrSession.getSessionStatus().toString());
} }
break; break;
case Message.ENCRYPTION_AXOLOTL: case Message.ENCRYPTION_AXOLOTL:
message.setFingerprint(account.getAxolotlService().getOwnFingerprint()); message.setFingerprint(account.getAxolotlService().getOwnFingerprint());
if (message.needsUploading()) { if (message.needsUploading()) {
if (account.httpUploadAvailable(fileBackend.getFile(message,false).getSize()) if (account.httpUploadAvailable(fileBackend.getFile(message, false).getSize())
|| conversation.getMode() == Conversation.MODE_MULTI || conversation.getMode() == Conversation.MODE_MULTI
|| message.fixCounterpart()) { || message.fixCounterpart()) {
this.sendFileMessage(message, delay); this.sendFileMessage(message, delay);
@ -1255,7 +1257,7 @@ public class XmppConnectionService extends Service {
break; break;
case Message.ENCRYPTION_OTR: case Message.ENCRYPTION_OTR:
if (!conversation.hasValidOtrSession() && message.getCounterpart() != null) { if (!conversation.hasValidOtrSession() && message.getCounterpart() != null) {
Log.d(Config.LOGTAG,account.getJid().toBareJid()+": create otr session without starting for "+message.getContact().getJid()); Log.d(Config.LOGTAG, account.getJid().toBareJid() + ": create otr session without starting for " + message.getContact().getJid());
conversation.startOtrSession(message.getCounterpart().getResourcepart(), false); conversation.startOtrSession(message.getCounterpart().getResourcepart(), false);
} }
break; break;
@ -1365,7 +1367,7 @@ public class XmppConnectionService extends Service {
} }
public void pushBookmarks(Account account) { public void pushBookmarks(Account account) {
Log.d(Config.LOGTAG, account.getJid().toBareJid()+": pushing bookmarks"); Log.d(Config.LOGTAG, account.getJid().toBareJid() + ": pushing bookmarks");
IqPacket iqPacket = new IqPacket(IqPacket.TYPE.SET); IqPacket iqPacket = new IqPacket(IqPacket.TYPE.SET);
Element query = iqPacket.query("jabber:iq:private"); Element query = iqPacket.query("jabber:iq:private");
Element storage = query.addChild("storage", "storage:bookmarks"); Element storage = query.addChild("storage", "storage:bookmarks");
@ -1381,31 +1383,31 @@ public class XmppConnectionService extends Service {
for (Account account : this.accounts) { for (Account account : this.accounts) {
accountLookupTable.put(account.getUuid(), account); accountLookupTable.put(account.getUuid(), account);
} }
Log.d(Config.LOGTAG,"restoring conversations..."); Log.d(Config.LOGTAG, "restoring conversations...");
final long startTimeConversationsRestore = SystemClock.elapsedRealtime(); final long startTimeConversationsRestore = SystemClock.elapsedRealtime();
this.conversations.addAll(databaseBackend.getConversations(Conversation.STATUS_AVAILABLE)); this.conversations.addAll(databaseBackend.getConversations(Conversation.STATUS_AVAILABLE));
for(Iterator<Conversation> iterator = conversations.listIterator(); iterator.hasNext();) { for (Iterator<Conversation> iterator = conversations.listIterator(); iterator.hasNext(); ) {
Conversation conversation = iterator.next(); Conversation conversation = iterator.next();
Account account = accountLookupTable.get(conversation.getAccountUuid()); Account account = accountLookupTable.get(conversation.getAccountUuid());
if (account != null) { if (account != null) {
conversation.setAccount(account); conversation.setAccount(account);
} else { } else {
Log.e(Config.LOGTAG,"unable to restore Conversations with "+conversation.getJid()); Log.e(Config.LOGTAG, "unable to restore Conversations with " + conversation.getJid());
iterator.remove(); iterator.remove();
} }
} }
long diffConversationsRestore = SystemClock.elapsedRealtime() - startTimeConversationsRestore; long diffConversationsRestore = SystemClock.elapsedRealtime() - startTimeConversationsRestore;
Log.d(Config.LOGTAG,"finished restoring conversations in "+diffConversationsRestore+"ms"); Log.d(Config.LOGTAG, "finished restoring conversations in " + diffConversationsRestore + "ms");
Runnable runnable = new Runnable() { Runnable runnable = new Runnable() {
@Override @Override
public void run() { public void run() {
long deletionDate = getAutomaticMessageDeletionDate(); long deletionDate = getAutomaticMessageDeletionDate();
mLastExpiryRun.set(SystemClock.elapsedRealtime()); mLastExpiryRun.set(SystemClock.elapsedRealtime());
if (deletionDate > 0) { if (deletionDate > 0) {
Log.d(Config.LOGTAG, "deleting messages that are older than "+AbstractGenerator.getTimestamp(deletionDate)); Log.d(Config.LOGTAG, "deleting messages that are older than " + AbstractGenerator.getTimestamp(deletionDate));
databaseBackend.expireOldMessages(deletionDate); databaseBackend.expireOldMessages(deletionDate);
} }
Log.d(Config.LOGTAG,"restoring roster..."); Log.d(Config.LOGTAG, "restoring roster...");
for (Account account : accounts) { for (Account account : accounts) {
databaseBackend.readRoster(account.getRoster()); databaseBackend.readRoster(account.getRoster());
account.initAccountServices(XmppConnectionService.this); //roster needs to be loaded at this stage account.initAccountServices(XmppConnectionService.this); //roster needs to be loaded at this stage
@ -1434,7 +1436,7 @@ public class XmppConnectionService extends Service {
mNotificationService.finishBacklog(false); mNotificationService.finishBacklog(false);
mRestoredFromDatabase = true; mRestoredFromDatabase = true;
final long diffMessageRestore = SystemClock.elapsedRealtime() - startMessageRestore; final long diffMessageRestore = SystemClock.elapsedRealtime() - startMessageRestore;
Log.d(Config.LOGTAG, "finished restoring messages in "+diffMessageRestore+"ms"); Log.d(Config.LOGTAG, "finished restoring messages in " + diffMessageRestore + "ms");
updateConversationUi(); updateConversationUi();
} }
}; };
@ -1481,7 +1483,7 @@ public class XmppConnectionService extends Service {
} }
} }
Log.d(Config.LOGTAG, "finished merging phone contacts"); Log.d(Config.LOGTAG, "finished merging phone contacts");
mShortcutService.refresh(mInitialAddressbookSyncCompleted.compareAndSet(false,true)); mShortcutService.refresh(mInitialAddressbookSyncCompleted.compareAndSet(false, true));
updateAccountUi(); updateAccountUi();
} }
}); });
@ -1510,7 +1512,7 @@ public class XmppConnectionService extends Service {
} }
private void markFileDeleted(final String path) { private void markFileDeleted(final String path) {
Log.d(Config.LOGTAG,"deleted file "+path); Log.d(Config.LOGTAG, "deleted file " + path);
for (Conversation conversation : getConversations()) { for (Conversation conversation : getConversations()) {
conversation.findMessagesWithFiles(new Conversation.OnMessageFound() { conversation.findMessagesWithFiles(new Conversation.OnMessageFound() {
@Override @Override
@ -1526,7 +1528,7 @@ public class XmppConnectionService extends Service {
updateConversationUi(); updateConversationUi();
} }
} else { } else {
Log.d(Config.LOGTAG,"found matching message for file "+path+" but file still exists"); Log.d(Config.LOGTAG, "found matching message for file " + path + " but file still exists");
} }
} }
} }
@ -1599,7 +1601,7 @@ public class XmppConnectionService extends Service {
public List<Conversation> findAllConferencesWith(Contact contact) { public List<Conversation> findAllConferencesWith(Contact contact) {
ArrayList<Conversation> results = new ArrayList<>(); ArrayList<Conversation> results = new ArrayList<>();
for(Conversation conversation : conversations) { for (Conversation conversation : conversations) {
if (conversation.getMode() == Conversation.MODE_MULTI if (conversation.getMode() == Conversation.MODE_MULTI
&& conversation.getMucOptions().isContactInRoom(contact)) { && conversation.getMucOptions().isContactInRoom(contact)) {
results.add(conversation); results.add(conversation);
@ -1631,7 +1633,7 @@ public class XmppConnectionService extends Service {
} }
public Conversation findOrCreateConversation(Account account, Jid jid, boolean muc, final boolean async) { public Conversation findOrCreateConversation(Account account, Jid jid, boolean muc, final boolean async) {
return this.findOrCreateConversation(account,jid,muc,false, 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) { public Conversation findOrCreateConversation(final Account account, final Jid jid, final boolean muc, final boolean joinAfterCreate, final boolean async) {
@ -1657,7 +1659,7 @@ public class XmppConnectionService extends Service {
conversation.setContactJid(jid.toBareJid()); conversation.setContactJid(jid.toBareJid());
} }
databaseBackend.updateConversation(conversation); databaseBackend.updateConversation(conversation);
loadMessagesFromDb = conversation.messagesLoaded.compareAndSet(true,false); loadMessagesFromDb = conversation.messagesLoaded.compareAndSet(true, false);
} else { } else {
String conversationName; String conversationName;
Contact contact = account.getRoster().getContact(jid); Contact contact = account.getRoster().getContact(jid);
@ -1692,7 +1694,7 @@ public class XmppConnectionService extends Service {
mMessageArchiveService.query(c); mMessageArchiveService.query(c);
} else { } else {
if (query.getConversation() == null) { if (query.getConversation() == null) {
mMessageArchiveService.query(c, query.getStart(),query.isCatchup()); mMessageArchiveService.query(c, query.getStart(), query.isCatchup());
} }
} }
} }
@ -1753,7 +1755,7 @@ public class XmppConnectionService extends Service {
} }
private void syncEnabledAccountSetting() { private void syncEnabledAccountSetting() {
getPreferences().edit().putBoolean(EventReceiver.SETTING_ENABLED_ACCOUNTS,hasEnabledAccounts()).apply(); getPreferences().edit().putBoolean(EventReceiver.SETTING_ENABLED_ACCOUNTS, hasEnabledAccounts()).apply();
} }
public void createAccountFromKey(final String alias, final OnAccountCreated callback) { public void createAccountFromKey(final String alias, final OnAccountCreated callback) {
@ -1794,10 +1796,10 @@ public class XmppConnectionService extends Service {
} }
public void updateKeyInAccount(final Account account, final String alias) { public void updateKeyInAccount(final Account account, final String alias) {
Log.d(Config.LOGTAG, account.getJid().toBareJid()+": update key in account " + alias); Log.d(Config.LOGTAG, account.getJid().toBareJid() + ": update key in account " + alias);
try { try {
X509Certificate[] chain = KeyChain.getCertificateChain(XmppConnectionService.this, alias); X509Certificate[] chain = KeyChain.getCertificateChain(XmppConnectionService.this, alias);
Log.d(Config.LOGTAG,account.getJid().toBareJid()+" loaded certificate chain"); Log.d(Config.LOGTAG, account.getJid().toBareJid() + " loaded certificate chain");
Pair<Jid, String> info = CryptoHelper.extractJidAndName(chain[0]); Pair<Jid, String> info = CryptoHelper.extractJidAndName(chain[0]);
if (account.getJid().toBareJid().equals(info.first)) { if (account.getJid().toBareJid().equals(info.first)) {
account.setPrivateKeyAlias(alias); account.setPrivateKeyAlias(alias);
@ -1876,7 +1878,7 @@ public class XmppConnectionService extends Service {
@Override @Override
public void run() { public void run() {
if (!databaseBackend.deleteAccount(account)) { if (!databaseBackend.deleteAccount(account)) {
Log.d(Config.LOGTAG,account.getJid().toBareJid()+": unable to delete account"); Log.d(Config.LOGTAG, account.getJid().toBareJid() + ": unable to delete account");
} }
} }
}; };
@ -1884,6 +1886,7 @@ public class XmppConnectionService extends Service {
this.accounts.remove(account); this.accounts.remove(account);
updateAccountUi(); updateAccountUi();
getNotificationService().updateErrorNotification(); getNotificationService().updateErrorNotification();
syncEnabledAccountSetting();
} }
} }
@ -2114,7 +2117,7 @@ public class XmppConnectionService extends Service {
if (account.getStatus() == Account.State.ONLINE) { if (account.getStatus() == Account.State.ONLINE) {
account.deactivateGracePeriod(); account.deactivateGracePeriod();
final XmppConnection connection = account.getXmppConnection(); final XmppConnection connection = account.getXmppConnection();
if (connection != null ) { if (connection != null) {
if (connection.getFeatures().csi()) { if (connection.getFeatures().csi()) {
connection.sendActive(); connection.sendActive();
} }
@ -2156,7 +2159,7 @@ public class XmppConnectionService extends Service {
} }
public void joinMuc(Conversation conversation) { public void joinMuc(Conversation conversation) {
joinMuc(conversation,null, false); joinMuc(conversation, null, false);
} }
public void joinMuc(Conversation conversation, boolean followedInvite) { public void joinMuc(Conversation conversation, boolean followedInvite) {
@ -2164,7 +2167,7 @@ public class XmppConnectionService extends Service {
} }
private void joinMuc(Conversation conversation, final OnConferenceJoined onConferenceJoined) { private void joinMuc(Conversation conversation, final OnConferenceJoined onConferenceJoined) {
joinMuc(conversation,onConferenceJoined,false); joinMuc(conversation, onConferenceJoined, false);
} }
private void joinMuc(Conversation conversation, final OnConferenceJoined onConferenceJoined, final boolean followedInvite) { private void joinMuc(Conversation conversation, final OnConferenceJoined onConferenceJoined, final boolean followedInvite) {
@ -2214,7 +2217,7 @@ public class XmppConnectionService extends Service {
if (mucOptions.membersOnly() && mucOptions.nonanonymous()) { if (mucOptions.membersOnly() && mucOptions.nonanonymous()) {
fetchConferenceMembers(conversation); fetchConferenceMembers(conversation);
if (followedInvite && conversation.getBookmark() == null) { if (followedInvite && conversation.getBookmark() == null) {
saveConversationAsBookmark(conversation,null); saveConversationAsBookmark(conversation, null);
} }
} }
sendUnsentMessages(conversation); sendUnsentMessages(conversation);
@ -2248,7 +2251,7 @@ public class XmppConnectionService extends Service {
private void fetchConferenceMembers(final Conversation conversation) { private void fetchConferenceMembers(final Conversation conversation) {
final Account account = conversation.getAccount(); final Account account = conversation.getAccount();
final AxolotlService axolotlService = account.getAxolotlService(); final AxolotlService axolotlService = account.getAxolotlService();
final String[] affiliations = {"member","admin","owner"}; final String[] affiliations = {"member", "admin", "owner"};
OnIqPacketReceived callback = new OnIqPacketReceived() { OnIqPacketReceived callback = new OnIqPacketReceived() {
private int i = 0; private int i = 0;
@ -2259,9 +2262,9 @@ public class XmppConnectionService extends Service {
Element query = packet.query("http://jabber.org/protocol/muc#admin"); Element query = packet.query("http://jabber.org/protocol/muc#admin");
if (packet.getType() == IqPacket.TYPE.RESULT && query != null) { if (packet.getType() == IqPacket.TYPE.RESULT && query != null) {
for(Element child : query.getChildren()) { for (Element child : query.getChildren()) {
if ("item".equals(child.getName())) { if ("item".equals(child.getName())) {
MucOptions.User user = AbstractParser.parseItem(conversation,child); MucOptions.User user = AbstractParser.parseItem(conversation, child);
if (!user.realJidMatchesAccount()) { if (!user.realJidMatchesAccount()) {
boolean isNew = conversation.getMucOptions().updateUser(user); boolean isNew = conversation.getMucOptions().updateUser(user);
if (isNew && user.getRealJid() != null && axolotlService.hasEmptyDeviceList(user.getRealJid())) { if (isNew && user.getRealJid() != null && axolotlService.hasEmptyDeviceList(user.getRealJid())) {
@ -2272,7 +2275,7 @@ public class XmppConnectionService extends Service {
} }
} else { } else {
success = false; success = false;
Log.d(Config.LOGTAG,account.getJid().toBareJid()+": could not request affiliation "+affiliations[i]+" in "+conversation.getJid().toBareJid()); Log.d(Config.LOGTAG, account.getJid().toBareJid() + ": could not request affiliation " + affiliations[i] + " in " + conversation.getJid().toBareJid());
} }
++i; ++i;
if (i >= affiliations.length) { if (i >= affiliations.length) {
@ -2280,11 +2283,11 @@ public class XmppConnectionService extends Service {
if (success) { if (success) {
List<Jid> cryptoTargets = conversation.getAcceptedCryptoTargets(); List<Jid> cryptoTargets = conversation.getAcceptedCryptoTargets();
boolean changed = false; boolean changed = false;
for(ListIterator<Jid> iterator = cryptoTargets.listIterator(); iterator.hasNext();) { for (ListIterator<Jid> iterator = cryptoTargets.listIterator(); iterator.hasNext(); ) {
Jid jid = iterator.next(); Jid jid = iterator.next();
if (!members.contains(jid)) { if (!members.contains(jid)) {
iterator.remove(); iterator.remove();
Log.d(Config.LOGTAG,account.getJid().toBareJid()+": removed "+jid+" from crypto targets of "+conversation.getName()); Log.d(Config.LOGTAG, account.getJid().toBareJid() + ": removed " + jid + " from crypto targets of " + conversation.getName());
changed = true; changed = true;
} }
} }
@ -2293,17 +2296,17 @@ public class XmppConnectionService extends Service {
updateConversation(conversation); updateConversation(conversation);
} }
} }
Log.d(Config.LOGTAG,account.getJid().toBareJid()+": retrieved members for "+conversation.getJid().toBareJid()+": "+conversation.getMucOptions().getMembers()); Log.d(Config.LOGTAG, account.getJid().toBareJid() + ": retrieved members for " + conversation.getJid().toBareJid() + ": " + conversation.getMucOptions().getMembers());
getAvatarService().clear(conversation); getAvatarService().clear(conversation);
updateMucRosterUi(); updateMucRosterUi();
updateConversationUi(); updateConversationUi();
} }
} }
}; };
for(String affiliation : affiliations) { for (String affiliation : affiliations) {
sendIqPacket(account, mIqGenerator.queryAffiliation(conversation, affiliation), callback); sendIqPacket(account, mIqGenerator.queryAffiliation(conversation, affiliation), callback);
} }
Log.d(Config.LOGTAG,account.getJid().toBareJid()+": fetching members for "+conversation.getName()); Log.d(Config.LOGTAG, account.getJid().toBareJid() + ": fetching members for " + conversation.getName());
} }
public void providePasswordForMuc(Conversation conversation, String password) { public void providePasswordForMuc(Conversation conversation, String password) {
@ -2321,7 +2324,7 @@ public class XmppConnectionService extends Service {
} }
private boolean hasEnabledAccounts() { private boolean hasEnabledAccounts() {
for(Account account : this.accounts) { for (Account account : this.accounts) {
if (!account.isOptionSet(Account.OPTION_DISABLED)) { if (!account.isOptionSet(Account.OPTION_DISABLED)) {
return true; return true;
} }
@ -2416,9 +2419,9 @@ public class XmppConnectionService extends Service {
} }
public boolean createAdhocConference(final Account account, public boolean createAdhocConference(final Account account,
final String subject, final String subject,
final Iterable<Jid> jids, final Iterable<Jid> jids,
final UiCallback<Conversation> callback) { final UiCallback<Conversation> callback) {
Log.d(Config.LOGTAG, account.getJid().toBareJid().toString() + ": creating adhoc conference with " + jids.toString()); Log.d(Config.LOGTAG, account.getJid().toBareJid().toString() + ": creating adhoc conference with " + jids.toString());
if (account.getStatus() == Account.State.ONLINE) { if (account.getStatus() == Account.State.ONLINE) {
try { try {
@ -2488,7 +2491,7 @@ public class XmppConnectionService extends Service {
sendIqPacket(conversation.getAccount(), request, new OnIqPacketReceived() { sendIqPacket(conversation.getAccount(), request, new OnIqPacketReceived() {
@Override @Override
public void onIqPacketReceived(Account account, IqPacket packet) { public void onIqPacketReceived(Account account, IqPacket packet) {
Element query = packet.findChild("query","http://jabber.org/protocol/disco#info"); Element query = packet.findChild("query", "http://jabber.org/protocol/disco#info");
if (packet.getType() == IqPacket.TYPE.RESULT && query != null) { if (packet.getType() == IqPacket.TYPE.RESULT && query != null) {
ArrayList<String> features = new ArrayList<>(); ArrayList<String> features = new ArrayList<>();
for (Element child : query.getChildren()) { for (Element child : query.getChildren()) {
@ -2507,7 +2510,7 @@ public class XmppConnectionService extends Service {
if (callback != null) { if (callback != null) {
callback.onConferenceConfigurationFetched(conversation); callback.onConferenceConfigurationFetched(conversation);
} }
Log.d(Config.LOGTAG,account.getJid().toBareJid()+": fetched muc configuration for "+conversation.getJid().toBareJid()+" - "+features.toString()); Log.d(Config.LOGTAG, account.getJid().toBareJid() + ": fetched muc configuration for " + conversation.getJid().toBareJid() + " - " + features.toString());
updateConversationUi(); updateConversationUi();
} else if (packet.getType() == IqPacket.TYPE.ERROR) { } else if (packet.getType() == IqPacket.TYPE.ERROR) {
if (callback != null) { if (callback != null) {
@ -2519,17 +2522,17 @@ public class XmppConnectionService extends Service {
} }
public void pushNodeConfiguration(Account account, final String node, final Bundle options, final OnConfigurationPushed callback) { public void pushNodeConfiguration(Account account, final String node, final Bundle options, final OnConfigurationPushed callback) {
pushNodeConfiguration(account,account.getJid().toBareJid(),node,options,callback); pushNodeConfiguration(account, account.getJid().toBareJid(), node, options, callback);
} }
public void pushNodeConfiguration(Account account, final Jid jid, final String node, final Bundle options, final OnConfigurationPushed callback) { public void pushNodeConfiguration(Account account, final Jid jid, final String node, final Bundle options, final OnConfigurationPushed callback) {
sendIqPacket(account, mIqGenerator.requestPubsubConfiguration(jid,node), new OnIqPacketReceived() { sendIqPacket(account, mIqGenerator.requestPubsubConfiguration(jid, node), new OnIqPacketReceived() {
@Override @Override
public void onIqPacketReceived(Account account, IqPacket packet) { public void onIqPacketReceived(Account account, IqPacket packet) {
if (packet.getType() == IqPacket.TYPE.RESULT) { if (packet.getType() == IqPacket.TYPE.RESULT) {
Element pubsub = packet.findChild("pubsub","http://jabber.org/protocol/pubsub#owner"); Element pubsub = packet.findChild("pubsub", "http://jabber.org/protocol/pubsub#owner");
Element configuration = pubsub == null ? null : pubsub.findChild("configure"); Element configuration = pubsub == null ? null : pubsub.findChild("configure");
Element x = configuration == null ? null : configuration.findChild("x","jabber:x:data"); Element x = configuration == null ? null : configuration.findChild("x", "jabber:x:data");
if (x != null) { if (x != null) {
Data data = Data.parse(x); Data data = Data.parse(x);
data.submit(options); data.submit(options);
@ -2539,14 +2542,14 @@ public class XmppConnectionService extends Service {
if (packet.getType() == IqPacket.TYPE.RESULT && callback != null) { if (packet.getType() == IqPacket.TYPE.RESULT && callback != null) {
callback.onPushSucceeded(); callback.onPushSucceeded();
} else { } else {
Log.d(Config.LOGTAG,packet.toString()); Log.d(Config.LOGTAG, packet.toString());
} }
} }
}); });
} else if (callback !=null) { } else if (callback != null) {
callback.onPushFailed(); callback.onPushFailed();
} }
} else if (callback != null){ } else if (callback != null) {
callback.onPushFailed(); callback.onPushFailed();
} }
} }
@ -2825,20 +2828,20 @@ public class XmppConnectionService extends Service {
getAvatarService().clear(account); getAvatarService().clear(account);
databaseBackend.updateAccount(account); databaseBackend.updateAccount(account);
} }
Log.d(Config.LOGTAG,account.getJid().toBareJid()+": published avatar "+(avatar.size/1024)+"KiB"); Log.d(Config.LOGTAG, account.getJid().toBareJid() + ": published avatar " + (avatar.size / 1024) + "KiB");
if (callback != null) { if (callback != null) {
callback.success(avatar); callback.success(avatar);
} }
} else { } else {
if (callback != null) { if (callback != null) {
callback.error(R.string.error_publish_avatar_server_reject,avatar); callback.error(R.string.error_publish_avatar_server_reject, avatar);
} }
} }
} }
}); });
} else { } else {
Element error = result.findChild("error"); Element error = result.findChild("error");
Log.d(Config.LOGTAG,account.getJid().toBareJid()+": server rejected avatar "+(avatar.size/1024)+"KiB "+(error!=null?error.toString():"")); Log.d(Config.LOGTAG, account.getJid().toBareJid() + ": server rejected avatar " + (avatar.size / 1024) + "KiB " + (error != null ? error.toString() : ""));
if (callback != null) { if (callback != null) {
callback.error(R.string.error_publish_avatar_server_reject, avatar); callback.error(R.string.error_publish_avatar_server_reject, avatar);
} }
@ -2849,7 +2852,7 @@ public class XmppConnectionService extends Service {
public void republishAvatarIfNeeded(Account account) { public void republishAvatarIfNeeded(Account account) {
if (account.getAxolotlService().isPepBroken()) { if (account.getAxolotlService().isPepBroken()) {
Log.d(Config.LOGTAG,account.getJid().toBareJid()+": skipping republication of avatar because pep is broken"); Log.d(Config.LOGTAG, account.getJid().toBareJid() + ": skipping republication of avatar because pep is broken");
return; return;
} }
IqPacket packet = this.mIqGenerator.retrieveAvatarMetaData(null); IqPacket packet = this.mIqGenerator.retrieveAvatarMetaData(null);
@ -2880,10 +2883,10 @@ public class XmppConnectionService extends Service {
if (serverAvatar == null && account.getAvatar() != null) { if (serverAvatar == null && account.getAvatar() != null) {
Avatar avatar = fileBackend.getStoredPepAvatar(account.getAvatar()); Avatar avatar = fileBackend.getStoredPepAvatar(account.getAvatar());
if (avatar != null) { if (avatar != null) {
Log.d(Config.LOGTAG,account.getJid().toBareJid()+": avatar on server was null. republishing"); Log.d(Config.LOGTAG, account.getJid().toBareJid() + ": avatar on server was null. republishing");
publishAvatar(account, fileBackend.getStoredPepAvatar(account.getAvatar()), null); publishAvatar(account, fileBackend.getStoredPepAvatar(account.getAvatar()), null);
} else { } else {
Log.e(Config.LOGTAG, account.getJid().toBareJid()+": error rereading avatar"); Log.e(Config.LOGTAG, account.getJid().toBareJid() + ": error rereading avatar");
} }
} }
} }
@ -2989,7 +2992,7 @@ public class XmppConnectionService extends Service {
+ ": successfully fetched vCard avatar for " + avatar.owner); + ": successfully fetched vCard avatar for " + avatar.owner);
if (avatar.owner.isBareJid()) { if (avatar.owner.isBareJid()) {
if (account.getJid().toBareJid().equals(avatar.owner) && account.getAvatar() == null) { if (account.getJid().toBareJid().equals(avatar.owner) && account.getAvatar() == null) {
Log.d(Config.LOGTAG,account.getJid().toBareJid()+": had no avatar. replacing with vcard"); Log.d(Config.LOGTAG, account.getJid().toBareJid() + ": had no avatar. replacing with vcard");
account.setAvatar(avatar.getFilename()); account.setAvatar(avatar.getFilename());
databaseBackend.updateAccount(account); databaseBackend.updateAccount(account);
getAvatarService().clear(account); getAvatarService().clear(account);
@ -3028,7 +3031,7 @@ public class XmppConnectionService extends Service {
@Override @Override
public void onIqPacketReceived(Account account, IqPacket packet) { public void onIqPacketReceived(Account account, IqPacket packet) {
if (packet.getType() == IqPacket.TYPE.RESULT) { if (packet.getType() == IqPacket.TYPE.RESULT) {
Element pubsub = packet.findChild("pubsub","http://jabber.org/protocol/pubsub"); Element pubsub = packet.findChild("pubsub", "http://jabber.org/protocol/pubsub");
if (pubsub != null) { if (pubsub != null) {
Element items = pubsub.findChild("items"); Element items = pubsub.findChild("items");
if (items != null) { if (items != null) {
@ -3203,21 +3206,21 @@ public class XmppConnectionService extends Service {
} }
public long getAutomaticMessageDeletionDate() { public long getAutomaticMessageDeletionDate() {
final long timeout = getLongPreference(SettingsActivity.AUTOMATIC_MESSAGE_DELETION,R.integer.automatic_message_deletion); final long timeout = getLongPreference(SettingsActivity.AUTOMATIC_MESSAGE_DELETION, R.integer.automatic_message_deletion);
return timeout == 0 ? timeout : (System.currentTimeMillis() - (timeout * 1000)); return timeout == 0 ? timeout : (System.currentTimeMillis() - (timeout * 1000));
} }
public long getLongPreference(String name, @IntegerRes int res) { public long getLongPreference(String name, @IntegerRes int res) {
long defaultValue = getResources().getInteger(res); long defaultValue = getResources().getInteger(res);
try { try {
return Long.parseLong(getPreferences().getString(name,String.valueOf(defaultValue))); return Long.parseLong(getPreferences().getString(name, String.valueOf(defaultValue)));
} catch (NumberFormatException e) { } catch (NumberFormatException e) {
return defaultValue; return defaultValue;
} }
} }
public boolean getBooleanPreference(String name, @BoolRes int res) { public boolean getBooleanPreference(String name, @BoolRes int res) {
return getPreferences().getBoolean(name,getResources().getBoolean(res)); return getPreferences().getBoolean(name, getResources().getBoolean(res));
} }
public boolean confirmMessages() { public boolean confirmMessages() {
@ -3334,7 +3337,7 @@ public class XmppConnectionService extends Service {
} }
public boolean markRead(final Conversation conversation) { public boolean markRead(final Conversation conversation) {
return markRead(conversation,true); return markRead(conversation, true);
} }
public boolean markRead(final Conversation conversation, boolean clear) { public boolean markRead(final Conversation conversation, boolean clear) {
@ -3447,10 +3450,10 @@ public class XmppConnectionService extends Service {
} }
} }
} }
if(Config.DOMAIN_LOCK != null && !hosts.contains(Config.DOMAIN_LOCK)) { if (Config.DOMAIN_LOCK != null && !hosts.contains(Config.DOMAIN_LOCK)) {
hosts.add(Config.DOMAIN_LOCK); hosts.add(Config.DOMAIN_LOCK);
} }
if(Config.MAGIC_CREATE_DOMAIN != null && !hosts.contains(Config.MAGIC_CREATE_DOMAIN)) { if (Config.MAGIC_CREATE_DOMAIN != null && !hosts.contains(Config.MAGIC_CREATE_DOMAIN)) {
hosts.add(Config.MAGIC_CREATE_DOMAIN); hosts.add(Config.MAGIC_CREATE_DOMAIN);
} }
return hosts; return hosts;
@ -3464,7 +3467,7 @@ public class XmppConnectionService extends Service {
if (server != null && !mucServers.contains(server)) { if (server != null && !mucServers.contains(server)) {
mucServers.add(server); mucServers.add(server);
} }
for(Bookmark bookmark : account.getBookmarks()) { for (Bookmark bookmark : account.getBookmarks()) {
final Jid jid = bookmark.getJid(); final Jid jid = bookmark.getJid();
final String s = jid == null ? null : jid.getDomainpart(); final String s = jid == null ? null : jid.getDomainpart();
if (s != null && !mucServers.contains(s)) { if (s != null && !mucServers.contains(s)) {
@ -3512,7 +3515,7 @@ public class XmppConnectionService extends Service {
private void sendPresence(final Account account, final boolean includeIdleTimestamp) { private void sendPresence(final Account account, final boolean includeIdleTimestamp) {
PresencePacket packet; PresencePacket packet;
if (manuallyChangePresence()) { if (manuallyChangePresence()) {
packet = mPresenceGenerator.selfPresence(account, account.getPresenceStatus()); packet = mPresenceGenerator.selfPresence(account, account.getPresenceStatus());
String message = account.getPresenceStatusMessage(); String message = account.getPresenceStatusMessage();
if (message != null && !message.isEmpty()) { if (message != null && !message.isEmpty()) {
packet.addChild(new Element("status").setContent(message)); packet.addChild(new Element("status").setContent(message));
@ -3522,13 +3525,13 @@ public class XmppConnectionService extends Service {
} }
if (mLastActivity > 0 && includeIdleTimestamp) { if (mLastActivity > 0 && includeIdleTimestamp) {
long since = Math.min(mLastActivity, System.currentTimeMillis()); //don't send future dates long since = Math.min(mLastActivity, System.currentTimeMillis()); //don't send future dates
packet.addChild("idle",Namespace.IDLE).setAttribute("since", AbstractGenerator.getTimestamp(since)); packet.addChild("idle", Namespace.IDLE).setAttribute("since", AbstractGenerator.getTimestamp(since));
} }
sendPresencePacket(account, packet); sendPresencePacket(account, packet);
} }
private void deactivateGracePeriod() { private void deactivateGracePeriod() {
for(Account account : getAccounts()) { for (Account account : getAccounts()) {
account.deactivateGracePeriod(); account.deactivateGracePeriod();
} }
} }
@ -3543,7 +3546,7 @@ public class XmppConnectionService extends Service {
} }
private void refreshAllGcmTokens() { private void refreshAllGcmTokens() {
for(Account account : getAccounts()) { for (Account account : getAccounts()) {
if (account.isOnlineAndConnected() && mPushManagementService.available(account)) { if (account.isOnlineAndConnected() && mPushManagementService.available(account)) {
mPushManagementService.registerPushTokenOnServer(account); mPushManagementService.registerPushTokenOnServer(account);
} }
@ -3551,7 +3554,7 @@ public class XmppConnectionService extends Service {
} }
private void sendOfflinePresence(final Account account) { private void sendOfflinePresence(final Account account) {
Log.d(Config.LOGTAG,account.getJid().toBareJid()+": sending offline presence"); Log.d(Config.LOGTAG, account.getJid().toBareJid() + ": sending offline presence");
sendPresencePacket(account, mPresenceGenerator.sendOfflinePresence(account)); sendPresencePacket(account, mPresenceGenerator.sendOfflinePresence(account));
} }
@ -3594,7 +3597,7 @@ public class XmppConnectionService extends Service {
} }
public Conversation findFirstMuc(Jid jid) { public Conversation findFirstMuc(Jid jid) {
for(Conversation conversation : getConversations()) { for (Conversation conversation : getConversations()) {
if (conversation.getJid().toBareJid().equals(jid.toBareJid()) if (conversation.getJid().toBareJid().equals(jid.toBareJid())
&& conversation.getMode() == Conversation.MODE_MULTI) { && conversation.getMode() == Conversation.MODE_MULTI) {
return conversation; return conversation;
@ -3642,7 +3645,7 @@ public class XmppConnectionService extends Service {
} }
conversation.clearMessages(); conversation.clearMessages();
conversation.setHasMessagesLeftOnServer(false); //avoid messages getting loaded through mam conversation.setHasMessagesLeftOnServer(false); //avoid messages getting loaded through mam
conversation.setLastClearHistory(clearDate,reference); conversation.setLastClearHistory(clearDate, reference);
Runnable runnable = new Runnable() { Runnable runnable = new Runnable() {
@Override @Override
public void run() { public void run() {
@ -3666,7 +3669,7 @@ public class XmppConnectionService extends Service {
} }
} }
}); });
if (removeBlockedConversations(blockable.getAccount(),jid)) { if (removeBlockedConversations(blockable.getAccount(), jid)) {
updateConversationUi(); updateConversationUi();
return true; return true;
} else { } else {
@ -3681,7 +3684,7 @@ public class XmppConnectionService extends Service {
boolean removed = false; boolean removed = false;
synchronized (this.conversations) { synchronized (this.conversations) {
boolean domainJid = blockedJid.isDomainJid(); boolean domainJid = blockedJid.isDomainJid();
for(Conversation conversation : this.conversations) { for (Conversation conversation : this.conversations) {
boolean jidMatches = (domainJid && blockedJid.getDomainpart().equals(conversation.getJid().getDomainpart())) boolean jidMatches = (domainJid && blockedJid.getDomainpart().equals(conversation.getJid().getDomainpart()))
|| blockedJid.equals(conversation.getJid().toBareJid()); || blockedJid.equals(conversation.getJid().toBareJid());
if (conversation.getAccount() == account if (conversation.getAccount() == account
@ -3690,7 +3693,7 @@ public class XmppConnectionService extends Service {
this.conversations.remove(conversation); this.conversations.remove(conversation);
markRead(conversation); markRead(conversation);
conversation.setStatus(Conversation.STATUS_ARCHIVED); conversation.setStatus(Conversation.STATUS_ARCHIVED);
Log.d(Config.LOGTAG,account.getJid().toBareJid()+": archiving conversation "+conversation.getJid().toBareJid()+" because jid was blocked"); Log.d(Config.LOGTAG, account.getJid().toBareJid() + ": archiving conversation " + conversation.getJid().toBareJid() + " because jid was blocked");
updateConversation(conversation); updateConversation(conversation);
removed = true; removed = true;
} }
@ -3743,7 +3746,7 @@ public class XmppConnectionService extends Service {
} }
public void fetchCaps(Account account, final Jid jid, final Presence presence) { public void fetchCaps(Account account, final Jid jid, final Presence presence) {
final Pair<String,String> key = new Pair<>(presence.getHash(), presence.getVer()); final Pair<String, String> key = new Pair<>(presence.getHash(), presence.getVer());
ServiceDiscoveryResult disco = getCachedServiceDiscoveryResult(key); ServiceDiscoveryResult disco = getCachedServiceDiscoveryResult(key);
if (disco != null) { if (disco != null) {
presence.setServiceDiscoveryResult(disco); presence.setServiceDiscoveryResult(disco);
@ -3753,7 +3756,7 @@ public class XmppConnectionService extends Service {
IqPacket request = new IqPacket(IqPacket.TYPE.GET); IqPacket request = new IqPacket(IqPacket.TYPE.GET);
request.setTo(jid); request.setTo(jid);
request.query("http://jabber.org/protocol/disco#info"); request.query("http://jabber.org/protocol/disco#info");
Log.d(Config.LOGTAG,account.getJid().toBareJid()+": making disco request for "+key.second+" to "+jid); Log.d(Config.LOGTAG, account.getJid().toBareJid() + ": making disco request for " + key.second + " to " + jid);
sendIqPacket(account, request, new OnIqPacketReceived() { sendIqPacket(account, request, new OnIqPacketReceived() {
@Override @Override
public void onIqPacketReceived(Account account, IqPacket discoPacket) { public void onIqPacketReceived(Account account, IqPacket discoPacket) {
@ -3774,8 +3777,8 @@ public class XmppConnectionService extends Service {
} }
private void injectServiceDiscorveryResult(Roster roster, String hash, String ver, ServiceDiscoveryResult disco) { private void injectServiceDiscorveryResult(Roster roster, String hash, String ver, ServiceDiscoveryResult disco) {
for(Contact contact : roster.getContacts()) { for (Contact contact : roster.getContacts()) {
for(Presence presence : contact.getPresences().getPresences().values()) { for (Presence presence : contact.getPresences().getPresences().values()) {
if (hash.equals(presence.getHash()) && ver.equals(presence.getVer())) { if (hash.equals(presence.getHash()) && ver.equals(presence.getVer())) {
presence.setServiceDiscoveryResult(disco); presence.setServiceDiscoveryResult(disco);
} }
@ -3786,11 +3789,11 @@ public class XmppConnectionService extends Service {
public void fetchMamPreferences(Account account, final OnMamPreferencesFetched callback) { public void fetchMamPreferences(Account account, final OnMamPreferencesFetched callback) {
final boolean legacy = account.getXmppConnection().getFeatures().mamLegacy(); final boolean legacy = account.getXmppConnection().getFeatures().mamLegacy();
IqPacket request = new IqPacket(IqPacket.TYPE.GET); IqPacket request = new IqPacket(IqPacket.TYPE.GET);
request.addChild("prefs",legacy ? Namespace.MAM_LEGACY : Namespace.MAM); request.addChild("prefs", legacy ? Namespace.MAM_LEGACY : Namespace.MAM);
sendIqPacket(account, request, new OnIqPacketReceived() { sendIqPacket(account, request, new OnIqPacketReceived() {
@Override @Override
public void onIqPacketReceived(Account account, IqPacket packet) { public void onIqPacketReceived(Account account, IqPacket packet) {
Element prefs = packet.findChild("prefs",legacy ? Namespace.MAM_LEGACY : Namespace.MAM); Element prefs = packet.findChild("prefs", legacy ? Namespace.MAM_LEGACY : Namespace.MAM);
if (packet.getType() == IqPacket.TYPE.RESULT && prefs != null) { if (packet.getType() == IqPacket.TYPE.RESULT && prefs != null) {
callback.onPreferencesFetched(prefs); callback.onPreferencesFetched(prefs);
} else { } else {
@ -3806,7 +3809,7 @@ public class XmppConnectionService extends Service {
public Account getPendingAccount() { public Account getPendingAccount() {
Account pending = null; Account pending = null;
for(Account account : getAccounts()) { for (Account account : getAccounts()) {
if (account.isOptionSet(Account.OPTION_REGISTER)) { if (account.isOptionSet(Account.OPTION_REGISTER)) {
pending = account; pending = account;
} else { } else {
@ -3836,14 +3839,14 @@ public class XmppConnectionService extends Service {
if (!statusMessage.isEmpty()) { if (!statusMessage.isEmpty()) {
databaseBackend.insertPresenceTemplate(new PresenceTemplate(status, statusMessage)); databaseBackend.insertPresenceTemplate(new PresenceTemplate(status, statusMessage));
} }
for(Account account : getAccounts()) { for (Account account : getAccounts()) {
changeStatusReal(account, status, statusMessage, true); changeStatusReal(account, status, statusMessage, true);
} }
} }
public List<PresenceTemplate> getPresenceTemplates(Account account) { public List<PresenceTemplate> getPresenceTemplates(Account account) {
List<PresenceTemplate> templates = databaseBackend.getPresenceTemplates(); List<PresenceTemplate> templates = databaseBackend.getPresenceTemplates();
for(PresenceTemplate template : account.getSelfContact().getPresences().asTemplates()) { for (PresenceTemplate template : account.getSelfContact().getPresences().asTemplates()) {
if (!templates.contains(template)) { if (!templates.contains(template)) {
templates.add(0, template); templates.add(0, template);
} }
@ -3860,7 +3863,7 @@ public class XmppConnectionService extends Service {
if (name != null && !name.trim().isEmpty()) { if (name != null && !name.trim().isEmpty()) {
bookmark.setBookmarkName(name.trim()); bookmark.setBookmarkName(name.trim());
} }
bookmark.setAutojoin(getPreferences().getBoolean("autojoin",getResources().getBoolean(R.bool.autojoin))); bookmark.setAutojoin(getPreferences().getBoolean("autojoin", getResources().getBoolean(R.bool.autojoin)));
account.getBookmarks().add(bookmark); account.getBookmarks().add(bookmark);
pushBookmarks(account); pushBookmarks(account);
conversation.setBookmark(bookmark); conversation.setBookmark(bookmark);
@ -3870,20 +3873,20 @@ public class XmppConnectionService extends Service {
boolean needsRosterWrite = false; boolean needsRosterWrite = false;
boolean performedVerification = false; boolean performedVerification = false;
final AxolotlService axolotlService = contact.getAccount().getAxolotlService(); final AxolotlService axolotlService = contact.getAccount().getAxolotlService();
for(XmppUri.Fingerprint fp : fingerprints) { for (XmppUri.Fingerprint fp : fingerprints) {
if (fp.type == XmppUri.FingerprintType.OTR) { if (fp.type == XmppUri.FingerprintType.OTR) {
performedVerification |= contact.addOtrFingerprint(fp.fingerprint); performedVerification |= contact.addOtrFingerprint(fp.fingerprint);
needsRosterWrite |= performedVerification; needsRosterWrite |= performedVerification;
} else if (fp.type == XmppUri.FingerprintType.OMEMO) { } else if (fp.type == XmppUri.FingerprintType.OMEMO) {
String fingerprint = "05"+fp.fingerprint.replaceAll("\\s",""); String fingerprint = "05" + fp.fingerprint.replaceAll("\\s", "");
FingerprintStatus fingerprintStatus = axolotlService.getFingerprintTrust(fingerprint); FingerprintStatus fingerprintStatus = axolotlService.getFingerprintTrust(fingerprint);
if (fingerprintStatus != null) { if (fingerprintStatus != null) {
if (!fingerprintStatus.isVerified()) { if (!fingerprintStatus.isVerified()) {
performedVerification = true; performedVerification = true;
axolotlService.setFingerprintTrust(fingerprint,fingerprintStatus.toVerified()); axolotlService.setFingerprintTrust(fingerprint, fingerprintStatus.toVerified());
} }
} else { } else {
axolotlService.preVerifyFingerprint(contact,fingerprint); axolotlService.preVerifyFingerprint(contact, fingerprint);
} }
} }
} }
@ -3896,18 +3899,18 @@ public class XmppConnectionService extends Service {
public boolean verifyFingerprints(Account account, List<XmppUri.Fingerprint> fingerprints) { public boolean verifyFingerprints(Account account, List<XmppUri.Fingerprint> fingerprints) {
final AxolotlService axolotlService = account.getAxolotlService(); final AxolotlService axolotlService = account.getAxolotlService();
boolean verifiedSomething = false; boolean verifiedSomething = false;
for(XmppUri.Fingerprint fp : fingerprints) { for (XmppUri.Fingerprint fp : fingerprints) {
if (fp.type == XmppUri.FingerprintType.OMEMO) { if (fp.type == XmppUri.FingerprintType.OMEMO) {
String fingerprint = "05"+fp.fingerprint.replaceAll("\\s",""); String fingerprint = "05" + fp.fingerprint.replaceAll("\\s", "");
Log.d(Config.LOGTAG,"trying to verify own fp="+fingerprint); Log.d(Config.LOGTAG, "trying to verify own fp=" + fingerprint);
FingerprintStatus fingerprintStatus = axolotlService.getFingerprintTrust(fingerprint); FingerprintStatus fingerprintStatus = axolotlService.getFingerprintTrust(fingerprint);
if (fingerprintStatus != null) { if (fingerprintStatus != null) {
if (!fingerprintStatus.isVerified()) { if (!fingerprintStatus.isVerified()) {
axolotlService.setFingerprintTrust(fingerprint,fingerprintStatus.toVerified()); axolotlService.setFingerprintTrust(fingerprint, fingerprintStatus.toVerified());
verifiedSomething = true; verifiedSomething = true;
} }
} else { } else {
axolotlService.preVerifyFingerprint(account,fingerprint); axolotlService.preVerifyFingerprint(account, fingerprint);
verifiedSomething = true; verifiedSomething = true;
} }
} }
@ -3916,7 +3919,7 @@ public class XmppConnectionService extends Service {
} }
public boolean blindTrustBeforeVerification() { public boolean blindTrustBeforeVerification() {
return getBooleanPreference(SettingsActivity.BLIND_TRUST_BEFORE_VERIFICATION,R.bool.btbv); return getBooleanPreference(SettingsActivity.BLIND_TRUST_BEFORE_VERIFICATION, R.bool.btbv);
} }
public ShortcutService getShortcutService() { public ShortcutService getShortcutService() {
@ -3925,6 +3928,7 @@ public class XmppConnectionService extends Service {
public interface OnMamPreferencesFetched { public interface OnMamPreferencesFetched {
void onPreferencesFetched(Element prefs); void onPreferencesFetched(Element prefs);
void onPreferencesFetchFailed(); void onPreferencesFetchFailed();
} }
@ -3974,9 +3978,9 @@ public class XmppConnectionService extends Service {
public interface OnCaptchaRequested { public interface OnCaptchaRequested {
void onCaptchaRequested(Account account, void onCaptchaRequested(Account account,
String id, String id,
Data data, Data data,
Bitmap captcha); Bitmap captcha);
} }
public interface OnRosterUpdate { public interface OnRosterUpdate {