From 61997912fd8191153c67c38af436980460af7933 Mon Sep 17 00:00:00 2001 From: Daniel Gultsch Date: Mon, 4 Apr 2016 20:06:07 +0200 Subject: made sure the disco#items query has returned before finalizing the bind --- .../siacs/conversations/xmpp/XmppConnection.java | 36 ++++++++++++++-------- 1 file changed, 24 insertions(+), 12 deletions(-) (limited to 'src/main/java/eu/siacs') diff --git a/src/main/java/eu/siacs/conversations/xmpp/XmppConnection.java b/src/main/java/eu/siacs/conversations/xmpp/XmppConnection.java index 6371f115..b3fd122f 100644 --- a/src/main/java/eu/siacs/conversations/xmpp/XmppConnection.java +++ b/src/main/java/eu/siacs/conversations/xmpp/XmppConnection.java @@ -39,6 +39,8 @@ import java.util.Hashtable; import java.util.Iterator; import java.util.List; import java.util.Map.Entry; +import java.util.concurrent.atomic.AtomicBoolean; +import java.util.concurrent.atomic.AtomicInteger; import javax.net.ssl.HostnameVerifier; import javax.net.ssl.KeyManager; @@ -114,7 +116,8 @@ public class XmppConnection implements Runnable { private long lastConnect = 0; private long lastSessionStarted = 0; private long lastDiscoStarted = 0; - private int mPendingServiceDiscoveries = 0; + private AtomicInteger mPendingServiceDiscoveries = new AtomicInteger(0); + private AtomicBoolean mIsServiceItemsDiscoveryPending = new AtomicBoolean(true); private final ArrayList mPendingServiceDiscoveriesIds = new ArrayList<>(); private boolean mInteractive = false; private int attempt = 0; @@ -923,7 +926,7 @@ public class XmppConnection implements Runnable { disconnect(true); } } else { - Log.d(Config.LOGTAG, account.getJid() + ": disconnecting because of bind failure ("+packet.toString()); + Log.d(Config.LOGTAG, account.getJid() + ": disconnecting because of bind failure (" + packet.toString()); disconnect(true); } } @@ -1008,7 +1011,8 @@ public class XmppConnection implements Runnable { synchronized (this.disco) { this.disco.clear(); } - mPendingServiceDiscoveries = mServerIdentity == Identity.NIMBUZZ ? 1 : 0; + mPendingServiceDiscoveries.set(mServerIdentity == Identity.NIMBUZZ ? 1 : 0); + mIsServiceItemsDiscoveryPending.set(true); lastDiscoStarted = SystemClock.elapsedRealtime(); Log.d(Config.LOGTAG, account.getJid().toBareJid() + ": starting service discovery"); mXmppConnectionService.scheduleWakeUpCall(Config.CONNECT_DISCO_TIMEOUT, account.getUuid().hashCode()); @@ -1032,7 +1036,7 @@ public class XmppConnection implements Runnable { private void sendServiceDiscoveryInfo(final Jid jid) { if (mServerIdentity != Identity.NIMBUZZ) { - mPendingServiceDiscoveries++; + mPendingServiceDiscoveries.incrementAndGet(); } final IqPacket iq = new IqPacket(IqPacket.TYPE.GET); iq.setTo(jid); @@ -1077,14 +1081,8 @@ public class XmppConnection implements Runnable { Log.d(Config.LOGTAG, account.getJid().toBareJid() + ": could not query disco info for " + jid.toString()); } if (packet.getType() != IqPacket.TYPE.TIMEOUT) { - mPendingServiceDiscoveries--; - if (mPendingServiceDiscoveries == 0) { - Log.d(Config.LOGTAG,account.getJid().toBareJid()+": done with service discovery"); - Log.d(Config.LOGTAG, account.getJid().toBareJid() + ": online with resource " + account.getResource()); - if (bindListener != null) { - bindListener.onBind(account); - } - changeStatus(Account.State.ONLINE); + if (mPendingServiceDiscoveries.decrementAndGet() == 0 && !mIsServiceItemsDiscoveryPending.get()) { + finalizeBind(); } } } @@ -1094,6 +1092,14 @@ public class XmppConnection implements Runnable { } } + private void finalizeBind() { + Log.d(Config.LOGTAG, account.getJid().toBareJid() + ": online with resource " + account.getResource()); + if (bindListener != null) { + bindListener.onBind(account); + } + changeStatus(Account.State.ONLINE); + } + private void enableAdvancedStreamFeatures() { if (getFeatures().carbons() && !features.carbonsEnabled) { sendEnableCarbons(); @@ -1128,6 +1134,12 @@ public class XmppConnection implements Runnable { } else { Log.d(Config.LOGTAG, account.getJid().toBareJid() + ": could not query disco items of " + server); } + if (packet.getType() != IqPacket.TYPE.TIMEOUT) { + mIsServiceItemsDiscoveryPending.set(false); + if (mPendingServiceDiscoveries.get() == 0) { + finalizeBind(); + } + } } }); } -- cgit v1.2.3 From 57876879979a9842d646415139656e3ad5a3d22e Mon Sep 17 00:00:00 2001 From: Daniel Gultsch Date: Mon, 4 Apr 2016 20:07:09 +0200 Subject: removed unnecessary wait for disconnect --- .../java/eu/siacs/conversations/services/XmppConnectionService.java | 6 ------ 1 file changed, 6 deletions(-) (limited to 'src/main/java/eu/siacs') diff --git a/src/main/java/eu/siacs/conversations/services/XmppConnectionService.java b/src/main/java/eu/siacs/conversations/services/XmppConnectionService.java index 28ac4d19..e477046c 100644 --- a/src/main/java/eu/siacs/conversations/services/XmppConnectionService.java +++ b/src/main/java/eu/siacs/conversations/services/XmppConnectionService.java @@ -2571,12 +2571,6 @@ public class XmppConnectionService extends Service implements OnPhoneContactsLoa if (!account.isOptionSet(Account.OPTION_DISABLED)) { if (!force) { disconnect(account, false); - try { - Log.d(Config.LOGTAG, "wait for disconnect"); - Thread.sleep(500); //sleep wait for disconnect - } catch (InterruptedException e) { - //ignored - } } Thread thread = new Thread(connection); connection.setInteractive(interactive); -- cgit v1.2.3 From 0385e3a8d62ebe68a8c40a75ea95d3726d3839f3 Mon Sep 17 00:00:00 2001 From: Daniel Gultsch Date: Mon, 4 Apr 2016 20:35:40 +0200 Subject: switched around info and items query to avoid race condition --- src/main/java/eu/siacs/conversations/xmpp/XmppConnection.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/main/java/eu/siacs') diff --git a/src/main/java/eu/siacs/conversations/xmpp/XmppConnection.java b/src/main/java/eu/siacs/conversations/xmpp/XmppConnection.java index b3fd122f..58e510e1 100644 --- a/src/main/java/eu/siacs/conversations/xmpp/XmppConnection.java +++ b/src/main/java/eu/siacs/conversations/xmpp/XmppConnection.java @@ -1016,7 +1016,6 @@ public class XmppConnection implements Runnable { lastDiscoStarted = SystemClock.elapsedRealtime(); Log.d(Config.LOGTAG, account.getJid().toBareJid() + ": starting service discovery"); mXmppConnectionService.scheduleWakeUpCall(Config.CONNECT_DISCO_TIMEOUT, account.getUuid().hashCode()); - sendServiceDiscoveryItems(account.getServer()); Element caps = streamFeatures.findChild("c"); final String hash = caps == null ? null : caps.getAttribute("hash"); final String ver = caps == null ? null : caps.getAttribute("ver"); @@ -1031,6 +1030,7 @@ public class XmppConnection implements Runnable { disco.put(account.getServer(), discoveryResult); } sendServiceDiscoveryInfo(account.getJid().toBareJid()); + sendServiceDiscoveryItems(account.getServer()); this.lastSessionStarted = SystemClock.elapsedRealtime(); } -- cgit v1.2.3 From ecaf75e5ecf785dbe83a4d1ec5f9a76d22e688ad Mon Sep 17 00:00:00 2001 From: Daniel Gultsch Date: Tue, 5 Apr 2016 13:31:03 +0200 Subject: better detect broken pep mark pep as broken when publishing bundle or device list failed reset 'brokenness' when account is getting disabled --- .../eu/siacs/conversations/crypto/axolotl/AxolotlService.java | 11 +++++++++-- .../siacs/conversations/services/XmppConnectionService.java | 1 + 2 files changed, 10 insertions(+), 2 deletions(-) (limited to 'src/main/java/eu/siacs') diff --git a/src/main/java/eu/siacs/conversations/crypto/axolotl/AxolotlService.java b/src/main/java/eu/siacs/conversations/crypto/axolotl/AxolotlService.java index cc5c2491..a24e4530 100644 --- a/src/main/java/eu/siacs/conversations/crypto/axolotl/AxolotlService.java +++ b/src/main/java/eu/siacs/conversations/crypto/axolotl/AxolotlService.java @@ -314,6 +314,11 @@ public class AxolotlService implements OnAdvancedStreamFeaturesLoaded { return this.pepBroken; } + public void resetBrokenness() { + this.pepBroken = false; + numPublishTriesOnEmptyPep = 0; + } + public void regenerateKeys(boolean wipeOther) { axolotlStore.regenerate(); sessions.clear(); @@ -448,7 +453,8 @@ public class AxolotlService implements OnAdvancedStreamFeaturesLoaded { mXmppConnectionService.sendIqPacket(account, publish, new OnIqPacketReceived() { @Override public void onIqPacketReceived(Account account, IqPacket packet) { - if (packet.getType() != IqPacket.TYPE.RESULT) { + if (packet.getType() == IqPacket.TYPE.ERROR) { + pepBroken = true; Log.d(Config.LOGTAG, getLogprefix(account) + "Error received while publishing own device id" + packet.findChild("error")); } } @@ -612,7 +618,8 @@ public class AxolotlService implements OnAdvancedStreamFeaturesLoaded { Log.d(Config.LOGTAG, getLogprefix(account) + "Announcing device " + getOwnDeviceId()); publishOwnDeviceIdIfNeeded(); } - } else { + } else if (packet.getType() == IqPacket.TYPE.ERROR) { + pepBroken = true; Log.d(Config.LOGTAG, getLogprefix(account) + "Error received while publishing bundle: " + packet.findChild("error")); } } diff --git a/src/main/java/eu/siacs/conversations/services/XmppConnectionService.java b/src/main/java/eu/siacs/conversations/services/XmppConnectionService.java index e477046c..e9ac3832 100644 --- a/src/main/java/eu/siacs/conversations/services/XmppConnectionService.java +++ b/src/main/java/eu/siacs/conversations/services/XmppConnectionService.java @@ -2581,6 +2581,7 @@ public class XmppConnectionService extends Service implements OnPhoneContactsLoa disconnect(account, force); account.getRoster().clearPresences(); connection.resetEverything(); + account.getAxolotlService().resetBrokenness(); } } } -- cgit v1.2.3 From 290f0a123e117ce8e31ef3f9a2d1e896fb4c1ab9 Mon Sep 17 00:00:00 2001 From: Daniel Gultsch Date: Thu, 7 Apr 2016 19:20:45 +0200 Subject: prevent null pointer when checking http upload max size --- .../java/eu/siacs/conversations/ui/ConversationActivity.java | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) (limited to 'src/main/java/eu/siacs') diff --git a/src/main/java/eu/siacs/conversations/ui/ConversationActivity.java b/src/main/java/eu/siacs/conversations/ui/ConversationActivity.java index 184b5dc6..02a20380 100644 --- a/src/main/java/eu/siacs/conversations/ui/ConversationActivity.java +++ b/src/main/java/eu/siacs/conversations/ui/ConversationActivity.java @@ -1301,10 +1301,6 @@ public class ConversationActivity extends XmppActivity } else if (requestCode == ATTACHMENT_CHOICE_CHOOSE_FILE || requestCode == ATTACHMENT_CHOICE_RECORD_VOICE) { final List uris = extractUriFromIntent(data); final Conversation c = getSelectedConversation(); - final long max = c.getAccount() - .getXmppConnection() - .getFeatures() - .getMaxHttpUploadSize(); final OnPresenceSelected callback = new OnPresenceSelected() { @Override public void onPresenceSelected() { @@ -1317,8 +1313,8 @@ public class ConversationActivity extends XmppActivity } } }; - if (c.getMode() == Conversation.MODE_MULTI - || FileBackend.allFilesUnderSize(this, uris, max) + if (c == null || c.getMode() == Conversation.MODE_MULTI + || FileBackend.allFilesUnderSize(this, uris, getMaxHttpUploadSize(c)) || c.getNextEncryption() == Message.ENCRYPTION_OTR) { callback.onPresenceSelected(); } else { @@ -1367,6 +1363,10 @@ public class ConversationActivity extends XmppActivity } } + private long getMaxHttpUploadSize(Conversation conversation) { + return conversation.getAccount().getXmppConnection().getFeatures().getMaxHttpUploadSize(); + } + private void setNeverAskForBatteryOptimizationsAgain() { getPreferences().edit().putBoolean("show_battery_optimization", false).commit(); } -- cgit v1.2.3 From 0460702710fd46cac0850224f34a275ceb8e2c1f Mon Sep 17 00:00:00 2001 From: Daniel Gultsch Date: Thu, 7 Apr 2016 20:29:40 +0200 Subject: check file owner when attaching files or using them as avatar --- .../conversations/persistance/FileBackend.java | 33 ++++++++++++++++++++++ .../services/XmppConnectionService.java | 10 +++++++ .../ui/PublishProfilePictureActivity.java | 13 +++++++-- 3 files changed, 54 insertions(+), 2 deletions(-) (limited to 'src/main/java/eu/siacs') diff --git a/src/main/java/eu/siacs/conversations/persistance/FileBackend.java b/src/main/java/eu/siacs/conversations/persistance/FileBackend.java index 21ba4509..69b81569 100644 --- a/src/main/java/eu/siacs/conversations/persistance/FileBackend.java +++ b/src/main/java/eu/siacs/conversations/persistance/FileBackend.java @@ -1,5 +1,7 @@ package eu.siacs.conversations.persistance; +import android.annotation.TargetApi; +import android.content.ContentResolver; import android.content.Context; import android.content.Intent; import android.database.Cursor; @@ -9,8 +11,13 @@ import android.graphics.Canvas; import android.graphics.Matrix; import android.graphics.RectF; import android.net.Uri; +import android.os.Build; import android.os.Environment; +import android.os.ParcelFileDescriptor; import android.provider.OpenableColumns; +import android.system.ErrnoException; +import android.system.Os; +import android.system.StructStat; import android.util.Base64; import android.util.Base64OutputStream; import android.util.Log; @@ -19,6 +26,7 @@ import android.webkit.MimeTypeMap; import java.io.ByteArrayOutputStream; import java.io.Closeable; import java.io.File; +import java.io.FileDescriptor; import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.IOException; @@ -646,4 +654,29 @@ public class FileBackend { } } } + + + public static boolean weOwnFile(Uri uri) { + if (Build.VERSION.SDK_INT < Build.VERSION_CODES.LOLLIPOP) { + return false; + } else { + return uri != null + && ContentResolver.SCHEME_FILE.equals(uri.getScheme()) + && weOwnFileLollipop(uri); + } + } + + @TargetApi(Build.VERSION_CODES.LOLLIPOP) + private static boolean weOwnFileLollipop(Uri uri) { + try { + File file = new File(uri.getPath()); + FileDescriptor fd = ParcelFileDescriptor.open(file, ParcelFileDescriptor.MODE_READ_ONLY).getFileDescriptor(); + StructStat st = Os.fstat(fd); + return st.st_uid == android.os.Process.myUid(); + } catch (ErrnoException e) { + return true; + } catch (FileNotFoundException e) { + return false; + } + } } diff --git a/src/main/java/eu/siacs/conversations/services/XmppConnectionService.java b/src/main/java/eu/siacs/conversations/services/XmppConnectionService.java index e9ac3832..2aaf9b62 100644 --- a/src/main/java/eu/siacs/conversations/services/XmppConnectionService.java +++ b/src/main/java/eu/siacs/conversations/services/XmppConnectionService.java @@ -403,6 +403,11 @@ public class XmppConnectionService extends Service implements OnPhoneContactsLoa public void attachFileToConversation(final Conversation conversation, final Uri uri, final UiCallback callback) { + if (FileBackend.weOwnFile(uri)) { + Log.d(Config.LOGTAG,"trying to attach file that belonged to us"); + callback.error(R.string.security_error_invalid_file_access, null); + return; + } final Message message; if (conversation.getNextEncryption() == Message.ENCRYPTION_PGP) { message = new Message(conversation, "", Message.ENCRYPTION_DECRYPTED); @@ -441,6 +446,11 @@ public class XmppConnectionService extends Service implements OnPhoneContactsLoa } public void attachImageToConversation(final Conversation conversation, final Uri uri, final UiCallback callback) { + if (FileBackend.weOwnFile(uri)) { + Log.d(Config.LOGTAG,"trying to attach file that belonged to us"); + callback.error(R.string.security_error_invalid_file_access, null); + return; + } final String compressPictures = getCompressPicturesPreference(); if ("never".equals(compressPictures) || ("auto".equals(compressPictures) && getFileBackend().useImageAsIs(uri))) { diff --git a/src/main/java/eu/siacs/conversations/ui/PublishProfilePictureActivity.java b/src/main/java/eu/siacs/conversations/ui/PublishProfilePictureActivity.java index 88645c4a..27a3efe5 100644 --- a/src/main/java/eu/siacs/conversations/ui/PublishProfilePictureActivity.java +++ b/src/main/java/eu/siacs/conversations/ui/PublishProfilePictureActivity.java @@ -23,6 +23,7 @@ import java.io.File; import eu.siacs.conversations.Config; import eu.siacs.conversations.R; import eu.siacs.conversations.entities.Account; +import eu.siacs.conversations.persistance.FileBackend; import eu.siacs.conversations.utils.FileUtils; import eu.siacs.conversations.utils.PhoneHelper; import eu.siacs.conversations.xmpp.pep.Avatar; @@ -187,9 +188,13 @@ public class PublishProfilePictureActivity extends XmppActivity { protected void onActivityResult(int requestCode, int resultCode, final Intent data) { super.onActivityResult(requestCode, resultCode, data); if (resultCode == RESULT_OK) { + Uri source = data.getData(); switch (requestCode) { case REQUEST_CHOOSE_FILE_AND_CROP: - Uri source = data.getData(); + if (FileBackend.weOwnFile(source)) { + Toast.makeText(this,R.string.security_error_invalid_file_access,Toast.LENGTH_SHORT).show(); + return; + } String original = FileUtils.getPath(this, source); if (original != null) { source = Uri.parse("file://"+original); @@ -199,7 +204,11 @@ public class PublishProfilePictureActivity extends XmppActivity { Crop.of(source, destination).asSquare().withMaxSize(size, size).start(this); break; case REQUEST_CHOOSE_FILE: - this.avatarUri = data.getData(); + if (FileBackend.weOwnFile(source)) { + Toast.makeText(this,R.string.security_error_invalid_file_access,Toast.LENGTH_SHORT).show(); + return; + } + this.avatarUri = source; if (xmppConnectionServiceBound) { loadImageIntoPreview(this.avatarUri); } -- cgit v1.2.3 From db0301310bcb4fa238df4839d793162727270dc1 Mon Sep 17 00:00:00 2001 From: Daniel Gultsch Date: Fri, 8 Apr 2016 18:28:40 +0200 Subject: removed ernoexception in exchange for a regular exeption to prevent verify error on <5.0 --- src/main/java/eu/siacs/conversations/persistance/FileBackend.java | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) (limited to 'src/main/java/eu/siacs') diff --git a/src/main/java/eu/siacs/conversations/persistance/FileBackend.java b/src/main/java/eu/siacs/conversations/persistance/FileBackend.java index 69b81569..0861a3a8 100644 --- a/src/main/java/eu/siacs/conversations/persistance/FileBackend.java +++ b/src/main/java/eu/siacs/conversations/persistance/FileBackend.java @@ -15,7 +15,6 @@ import android.os.Build; import android.os.Environment; import android.os.ParcelFileDescriptor; import android.provider.OpenableColumns; -import android.system.ErrnoException; import android.system.Os; import android.system.StructStat; import android.util.Base64; @@ -673,10 +672,10 @@ public class FileBackend { FileDescriptor fd = ParcelFileDescriptor.open(file, ParcelFileDescriptor.MODE_READ_ONLY).getFileDescriptor(); StructStat st = Os.fstat(fd); return st.st_uid == android.os.Process.myUid(); - } catch (ErrnoException e) { - return true; } catch (FileNotFoundException e) { return false; + } catch (Exception e) { + return true; } } } -- cgit v1.2.3 From a8ebc5fafcd0c200b960015f7a33ce71d1689a7f Mon Sep 17 00:00:00 2001 From: Daniel Gultsch Date: Fri, 8 Apr 2016 20:20:37 +0200 Subject: add required disco#items query to timeout list --- src/main/java/eu/siacs/conversations/xmpp/XmppConnection.java | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) (limited to 'src/main/java/eu/siacs') diff --git a/src/main/java/eu/siacs/conversations/xmpp/XmppConnection.java b/src/main/java/eu/siacs/conversations/xmpp/XmppConnection.java index 58e510e1..19d4fcba 100644 --- a/src/main/java/eu/siacs/conversations/xmpp/XmppConnection.java +++ b/src/main/java/eu/siacs/conversations/xmpp/XmppConnection.java @@ -1117,7 +1117,7 @@ public class XmppConnection implements Runnable { final IqPacket iq = new IqPacket(IqPacket.TYPE.GET); iq.setTo(server.toDomainJid()); iq.query("http://jabber.org/protocol/disco#items"); - this.sendIqPacket(iq, new OnIqPacketReceived() { + String id = this.sendIqPacket(iq, new OnIqPacketReceived() { @Override public void onIqPacketReceived(final Account account, final IqPacket packet) { @@ -1142,6 +1142,9 @@ public class XmppConnection implements Runnable { } } }); + synchronized (this.mPendingServiceDiscoveriesIds) { + this.mPendingServiceDiscoveriesIds.add(id); + } } private void sendEnableCarbons() { -- cgit v1.2.3 From 14b46c3ee7aa860d349bcf8418b6ad35715c9ec4 Mon Sep 17 00:00:00 2001 From: Daniel Gultsch Date: Sat, 9 Apr 2016 08:53:58 +0200 Subject: transform nimbuzz workaround into a more general 'waitForDisco' condition --- .../eu/siacs/conversations/xmpp/XmppConnection.java | 17 +++++++++++------ 1 file changed, 11 insertions(+), 6 deletions(-) (limited to 'src/main/java/eu/siacs') diff --git a/src/main/java/eu/siacs/conversations/xmpp/XmppConnection.java b/src/main/java/eu/siacs/conversations/xmpp/XmppConnection.java index 19d4fcba..6427c347 100644 --- a/src/main/java/eu/siacs/conversations/xmpp/XmppConnection.java +++ b/src/main/java/eu/siacs/conversations/xmpp/XmppConnection.java @@ -118,6 +118,7 @@ public class XmppConnection implements Runnable { private long lastDiscoStarted = 0; private AtomicInteger mPendingServiceDiscoveries = new AtomicInteger(0); private AtomicBoolean mIsServiceItemsDiscoveryPending = new AtomicBoolean(true); + private boolean mWaitForDisco = true; private final ArrayList mPendingServiceDiscoveriesIds = new ArrayList<>(); private boolean mInteractive = false; private int attempt = 0; @@ -1011,8 +1012,9 @@ public class XmppConnection implements Runnable { synchronized (this.disco) { this.disco.clear(); } - mPendingServiceDiscoveries.set(mServerIdentity == Identity.NIMBUZZ ? 1 : 0); + mPendingServiceDiscoveries.set(0); mIsServiceItemsDiscoveryPending.set(true); + mWaitForDisco = mServerIdentity != Identity.NIMBUZZ; lastDiscoStarted = SystemClock.elapsedRealtime(); Log.d(Config.LOGTAG, account.getJid().toBareJid() + ": starting service discovery"); mXmppConnectionService.scheduleWakeUpCall(Config.CONNECT_DISCO_TIMEOUT, account.getUuid().hashCode()); @@ -1031,13 +1033,14 @@ public class XmppConnection implements Runnable { } sendServiceDiscoveryInfo(account.getJid().toBareJid()); sendServiceDiscoveryItems(account.getServer()); + if (!mWaitForDisco) { + finalizeBind(); + } this.lastSessionStarted = SystemClock.elapsedRealtime(); } private void sendServiceDiscoveryInfo(final Jid jid) { - if (mServerIdentity != Identity.NIMBUZZ) { - mPendingServiceDiscoveries.incrementAndGet(); - } + mPendingServiceDiscoveries.incrementAndGet(); final IqPacket iq = new IqPacket(IqPacket.TYPE.GET); iq.setTo(jid); iq.query("http://jabber.org/protocol/disco#info"); @@ -1081,7 +1084,9 @@ public class XmppConnection implements Runnable { Log.d(Config.LOGTAG, account.getJid().toBareJid() + ": could not query disco info for " + jid.toString()); } if (packet.getType() != IqPacket.TYPE.TIMEOUT) { - if (mPendingServiceDiscoveries.decrementAndGet() == 0 && !mIsServiceItemsDiscoveryPending.get()) { + if (mPendingServiceDiscoveries.decrementAndGet() == 0 + && !mIsServiceItemsDiscoveryPending.get() + && mWaitForDisco) { finalizeBind(); } } @@ -1136,7 +1141,7 @@ public class XmppConnection implements Runnable { } if (packet.getType() != IqPacket.TYPE.TIMEOUT) { mIsServiceItemsDiscoveryPending.set(false); - if (mPendingServiceDiscoveries.get() == 0) { + if (mPendingServiceDiscoveries.get() == 0 && mWaitForDisco) { finalizeBind(); } } -- cgit v1.2.3 From 2713fd50c830e0c139ea4ae3194bdd60126bb968 Mon Sep 17 00:00:00 2001 From: Daniel Gultsch Date: Sat, 9 Apr 2016 10:29:34 +0200 Subject: use last received message id when querying archive --- .../services/MessageArchiveService.java | 24 +++++++++++++++------- 1 file changed, 17 insertions(+), 7 deletions(-) (limited to 'src/main/java/eu/siacs') diff --git a/src/main/java/eu/siacs/conversations/services/MessageArchiveService.java b/src/main/java/eu/siacs/conversations/services/MessageArchiveService.java index e8616bd8..a50b45b1 100644 --- a/src/main/java/eu/siacs/conversations/services/MessageArchiveService.java +++ b/src/main/java/eu/siacs/conversations/services/MessageArchiveService.java @@ -45,8 +45,10 @@ public class MessageArchiveService implements OnAdvancedStreamFeaturesLoaded { } } } - long startCatchup = getLastMessageTransmitted(account); + Pair pair = mXmppConnectionService.databaseBackend.getLastMessageReceived(account); + long startCatchup = pair == null ? 0 : pair.first; long endCatchup = account.getXmppConnection().getLastSessionEstablished(); + final Query query; if (startCatchup == 0) { return; } else if (endCatchup - startCatchup >= Config.MAM_MAX_CATCHUP) { @@ -57,8 +59,14 @@ public class MessageArchiveService implements OnAdvancedStreamFeaturesLoaded { this.query(conversation,startCatchup); } } + query = new Query(account, startCatchup, endCatchup); + } else { + if (pair.second == null) { + query = new Query(account, startCatchup, endCatchup); + } else { + query = new Query(account, pair.second, endCatchup); + } } - final Query query = new Query(account, startCatchup, endCatchup); this.queries.add(query); this.execute(query); } @@ -75,11 +83,6 @@ public class MessageArchiveService implements OnAdvancedStreamFeaturesLoaded { } } - private long getLastMessageTransmitted(final Account account) { - Pair pair = mXmppConnectionService.databaseBackend.getLastMessageReceived(account); - return pair == null ? 0 : pair.first; - } - public Query query(final Conversation conversation) { if (conversation.getLastMessageTransmitted() < 0 && conversation.countMessages() == 0) { return query(conversation, @@ -283,6 +286,13 @@ public class MessageArchiveService implements OnAdvancedStreamFeaturesLoaded { this.queryId = new BigInteger(50, mXmppConnectionService.getRNG()).toString(32); } + public Query(Account account, String reference, long end) { + this.account = account; + this.reference = reference; + this.end = end; + this.queryId = new BigInteger(50, mXmppConnectionService.getRNG()).toString(32); + } + private Query page(String reference) { Query query = new Query(this.account,this.start,this.end); query.reference = reference; -- cgit v1.2.3 From b99d70bfe74ce5dff1c8ed26d7f3dbd577a22125 Mon Sep 17 00:00:00 2001 From: Daniel Gultsch Date: Sat, 9 Apr 2016 10:59:54 +0200 Subject: don't show contact details when in conversations with self --- src/main/java/eu/siacs/conversations/entities/Conversation.java | 4 ++++ src/main/java/eu/siacs/conversations/ui/ConversationActivity.java | 1 + src/main/java/eu/siacs/conversations/ui/ConversationFragment.java | 4 +++- 3 files changed, 8 insertions(+), 1 deletion(-) (limited to 'src/main/java/eu/siacs') diff --git a/src/main/java/eu/siacs/conversations/entities/Conversation.java b/src/main/java/eu/siacs/conversations/entities/Conversation.java index 0252ea74..a3ae906b 100644 --- a/src/main/java/eu/siacs/conversations/entities/Conversation.java +++ b/src/main/java/eu/siacs/conversations/entities/Conversation.java @@ -336,6 +336,10 @@ public class Conversation extends AbstractEntity implements Blockable { return this.correctingMessage; } + public boolean withSelf() { + return getContact().isSelf(); + } + public interface OnMessageFound { void onMessageFound(final Message message); } diff --git a/src/main/java/eu/siacs/conversations/ui/ConversationActivity.java b/src/main/java/eu/siacs/conversations/ui/ConversationActivity.java index 02a20380..920c07af 100644 --- a/src/main/java/eu/siacs/conversations/ui/ConversationActivity.java +++ b/src/main/java/eu/siacs/conversations/ui/ConversationActivity.java @@ -411,6 +411,7 @@ public class ConversationActivity extends XmppActivity menuInviteContact.setVisible(getSelectedConversation().getMucOptions().canInvite()); menuSecure.setVisible((Config.supportOpenPgp() || Config.supportOmemo()) && Config.multipleEncryptionChoices()); //only if pgp is supported we have a choice } else { + menuContactDetails.setVisible(!this.getSelectedConversation().withSelf()); menuMucDetails.setVisible(false); menuSecure.setVisible(Config.multipleEncryptionChoices()); } diff --git a/src/main/java/eu/siacs/conversations/ui/ConversationFragment.java b/src/main/java/eu/siacs/conversations/ui/ConversationFragment.java index 1a834ae5..095bf58f 100644 --- a/src/main/java/eu/siacs/conversations/ui/ConversationFragment.java +++ b/src/main/java/eu/siacs/conversations/ui/ConversationFragment.java @@ -468,7 +468,9 @@ public class ConversationFragment extends Fragment implements EditMessage.Keyboa highlightInConference(user); } } else { - activity.switchToContactDetails(message.getContact(), message.getFingerprint()); + if (!message.getContact().isSelf()) { + activity.switchToContactDetails(message.getContact(), message.getFingerprint()); + } } } else { Account account = message.getConversation().getAccount(); -- cgit v1.2.3 From 65548ddccb7f63d623a86ad9a740ded87310e313 Mon Sep 17 00:00:00 2001 From: Daniel Gultsch Date: Sat, 9 Apr 2016 12:31:08 +0200 Subject: use startdate as lower bound when querying archive with after=x --- .../conversations/services/MessageArchiveService.java | 16 +++------------- 1 file changed, 3 insertions(+), 13 deletions(-) (limited to 'src/main/java/eu/siacs') diff --git a/src/main/java/eu/siacs/conversations/services/MessageArchiveService.java b/src/main/java/eu/siacs/conversations/services/MessageArchiveService.java index a50b45b1..06df1b38 100644 --- a/src/main/java/eu/siacs/conversations/services/MessageArchiveService.java +++ b/src/main/java/eu/siacs/conversations/services/MessageArchiveService.java @@ -61,11 +61,8 @@ public class MessageArchiveService implements OnAdvancedStreamFeaturesLoaded { } query = new Query(account, startCatchup, endCatchup); } else { - if (pair.second == null) { - query = new Query(account, startCatchup, endCatchup); - } else { - query = new Query(account, pair.second, endCatchup); - } + query = new Query(account, startCatchup, endCatchup); + query.reference = pair.second; } this.queries.add(query); this.execute(query); @@ -285,14 +282,7 @@ public class MessageArchiveService implements OnAdvancedStreamFeaturesLoaded { this.end = end; this.queryId = new BigInteger(50, mXmppConnectionService.getRNG()).toString(32); } - - public Query(Account account, String reference, long end) { - this.account = account; - this.reference = reference; - this.end = end; - this.queryId = new BigInteger(50, mXmppConnectionService.getRNG()).toString(32); - } - + private Query page(String reference) { Query query = new Query(this.account,this.start,this.end); query.reference = reference; -- cgit v1.2.3 From 83fab0650880873f0fb77697acc4c5102ad5f166 Mon Sep 17 00:00:00 2001 From: Daniel Gultsch Date: Sat, 9 Apr 2016 21:48:06 +0200 Subject: introduced setting to turn of notification led --- .../java/eu/siacs/conversations/services/NotificationService.java | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) (limited to 'src/main/java/eu/siacs') diff --git a/src/main/java/eu/siacs/conversations/services/NotificationService.java b/src/main/java/eu/siacs/conversations/services/NotificationService.java index cec9a3ef..003f5471 100644 --- a/src/main/java/eu/siacs/conversations/services/NotificationService.java +++ b/src/main/java/eu/siacs/conversations/services/NotificationService.java @@ -180,6 +180,7 @@ public class NotificationService { final String ringtone = preferences.getString("notification_ringtone", null); final boolean vibrate = preferences.getBoolean("vibrate_on_notification", true); + final boolean led = preferences.getBoolean("led", true); if (notifications.size() == 0) { notificationManager.cancel(NOTIFICATION_ID); @@ -210,7 +211,9 @@ public class NotificationService { mBuilder.setDefaults(0); mBuilder.setSmallIcon(R.drawable.ic_notification); mBuilder.setDeleteIntent(createDeleteIntent()); - mBuilder.setLights(0xff00FF00, 2000, 3000); + if (led) { + mBuilder.setLights(0xff00FF00, 2000, 3000); + } final Notification notification = mBuilder.build(); notificationManager.notify(NOTIFICATION_ID, notification); } -- cgit v1.2.3 From 607b7d159319e7591f9a1dac07e187abdb4cf278 Mon Sep 17 00:00:00 2001 From: Daniel Gultsch Date: Sun, 10 Apr 2016 00:18:14 +0200 Subject: moved authentication into seperate method. force close socket before changing status --- .../siacs/conversations/xmpp/XmppConnection.java | 82 ++++++++++++---------- 1 file changed, 44 insertions(+), 38 deletions(-) (limited to 'src/main/java/eu/siacs') diff --git a/src/main/java/eu/siacs/conversations/xmpp/XmppConnection.java b/src/main/java/eu/siacs/conversations/xmpp/XmppConnection.java index 6427c347..30cb96dc 100644 --- a/src/main/java/eu/siacs/conversations/xmpp/XmppConnection.java +++ b/src/main/java/eu/siacs/conversations/xmpp/XmppConnection.java @@ -183,16 +183,18 @@ public class XmppConnection implements Runnable { if (packet.getType() == IqPacket.TYPE.RESULT) { account.setOption(Account.OPTION_REGISTER, false); + forceCloseSocket(); changeStatus(Account.State.REGISTRATION_SUCCESSFUL); } else if (packet.hasChild("error") && (packet.findChild("error") .hasChild("conflict"))) { + forceCloseSocket(); changeStatus(Account.State.REGISTRATION_CONFLICT); } else { + forceCloseSocket(); changeStatus(Account.State.REGISTRATION_FAILED); Log.d(Config.LOGTAG, packet.toString()); } - disconnect(true); } }; } @@ -739,47 +741,12 @@ public class XmppConnection implements Runnable { } } else if (!this.streamFeatures.hasChild("register") && account.isOptionSet(Account.OPTION_REGISTER)) { + forceCloseSocket(); changeStatus(Account.State.REGISTRATION_NOT_SUPPORTED); - disconnect(true); } else if (this.streamFeatures.hasChild("mechanisms") && shouldAuthenticate && (features.encryptionEnabled || Config.ALLOW_NON_TLS_CONNECTIONS)) { - final List mechanisms = extractMechanisms(streamFeatures - .findChild("mechanisms")); - final Element auth = new Element("auth"); - auth.setAttribute("xmlns", "urn:ietf:params:xml:ns:xmpp-sasl"); - if (mechanisms.contains("EXTERNAL") && account.getPrivateKeyAlias() != null) { - saslMechanism = new External(tagWriter, account, mXmppConnectionService.getRNG()); - } else if (mechanisms.contains("SCRAM-SHA-1")) { - saslMechanism = new ScramSha1(tagWriter, account, mXmppConnectionService.getRNG()); - } else if (mechanisms.contains("PLAIN")) { - saslMechanism = new Plain(tagWriter, account); - } else if (mechanisms.contains("DIGEST-MD5")) { - saslMechanism = new DigestMd5(tagWriter, account, mXmppConnectionService.getRNG()); - } - if (saslMechanism != null) { - final JSONObject keys = account.getKeys(); - try { - if (keys.has(Account.PINNED_MECHANISM_KEY) && - keys.getInt(Account.PINNED_MECHANISM_KEY) > saslMechanism.getPriority()) { - Log.e(Config.LOGTAG, "Auth failed. Authentication mechanism " + saslMechanism.getMechanism() + - " has lower priority (" + String.valueOf(saslMechanism.getPriority()) + - ") than pinned priority (" + keys.getInt(Account.PINNED_MECHANISM_KEY) + - "). Possible downgrade attack?"); - throw new SecurityException(); - } - } catch (final JSONException e) { - Log.d(Config.LOGTAG, "Parse error while checking pinned auth mechanism"); - } - Log.d(Config.LOGTAG, account.getJid().toString() + ": Authenticating with " + saslMechanism.getMechanism()); - auth.setAttribute("mechanism", saslMechanism.getMechanism()); - if (!saslMechanism.getClientFirstMessage().isEmpty()) { - auth.setContent(saslMechanism.getClientFirstMessage()); - } - tagWriter.writeElement(auth); - } else { - throw new IncompatibleServerException(); - } + authenticate(); } else if (this.streamFeatures.hasChild("sm", "urn:xmpp:sm:" + smVersion) && streamId != null) { if (Config.EXTENDED_SM_LOGGING) { Log.d(Config.LOGTAG,account.getJid().toBareJid()+": resuming after stanza #"+stanzasReceived); @@ -795,6 +762,45 @@ public class XmppConnection implements Runnable { } } + private void authenticate() throws IOException { + final List mechanisms = extractMechanisms(streamFeatures + .findChild("mechanisms")); + final Element auth = new Element("auth"); + auth.setAttribute("xmlns", "urn:ietf:params:xml:ns:xmpp-sasl"); + if (mechanisms.contains("EXTERNAL") && account.getPrivateKeyAlias() != null) { + saslMechanism = new External(tagWriter, account, mXmppConnectionService.getRNG()); + } else if (mechanisms.contains("SCRAM-SHA-1")) { + saslMechanism = new ScramSha1(tagWriter, account, mXmppConnectionService.getRNG()); + } else if (mechanisms.contains("PLAIN")) { + saslMechanism = new Plain(tagWriter, account); + } else if (mechanisms.contains("DIGEST-MD5")) { + saslMechanism = new DigestMd5(tagWriter, account, mXmppConnectionService.getRNG()); + } + if (saslMechanism != null) { + final JSONObject keys = account.getKeys(); + try { + if (keys.has(Account.PINNED_MECHANISM_KEY) && + keys.getInt(Account.PINNED_MECHANISM_KEY) > saslMechanism.getPriority()) { + Log.e(Config.LOGTAG, "Auth failed. Authentication mechanism " + saslMechanism.getMechanism() + + " has lower priority (" + String.valueOf(saslMechanism.getPriority()) + + ") than pinned priority (" + keys.getInt(Account.PINNED_MECHANISM_KEY) + + "). Possible downgrade attack?"); + throw new SecurityException(); + } + } catch (final JSONException e) { + Log.d(Config.LOGTAG, "Parse error while checking pinned auth mechanism"); + } + Log.d(Config.LOGTAG, account.getJid().toString() + ": Authenticating with " + saslMechanism.getMechanism()); + auth.setAttribute("mechanism", saslMechanism.getMechanism()); + if (!saslMechanism.getClientFirstMessage().isEmpty()) { + auth.setContent(saslMechanism.getClientFirstMessage()); + } + tagWriter.writeElement(auth); + } else { + throw new IncompatibleServerException(); + } + } + private List extractMechanisms(final Element stream) { final ArrayList mechanisms = new ArrayList<>(stream .getChildren().size()); -- cgit v1.2.3 From 91b17c6925e24f68240b25d26f74a352191ff1af Mon Sep 17 00:00:00 2001 From: Daniel Gultsch Date: Sun, 10 Apr 2016 00:19:20 +0200 Subject: =?UTF-8?q?fixed=20'connecting=E2=80=A6'=20button?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/eu/siacs/conversations/ui/EditAccountActivity.java | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) (limited to 'src/main/java/eu/siacs') diff --git a/src/main/java/eu/siacs/conversations/ui/EditAccountActivity.java b/src/main/java/eu/siacs/conversations/ui/EditAccountActivity.java index 9d73290a..48ccb9f0 100644 --- a/src/main/java/eu/siacs/conversations/ui/EditAccountActivity.java +++ b/src/main/java/eu/siacs/conversations/ui/EditAccountActivity.java @@ -241,12 +241,11 @@ public class EditAccountActivity extends XmppActivity implements OnAccountUpdate mFetchingAvatar = true; xmppConnectionService.checkForAvatar(mAccount, mAvatarFetchCallback); } - } else { - updateSaveButton(); } if (mAccount != null) { updateAccountInformation(false); } + updateSaveButton(); } @Override @@ -335,7 +334,8 @@ public class EditAccountActivity extends XmppActivity implements OnAccountUpdate this.mSaveButton.setText(R.string.save); this.mSaveButton.setEnabled(true); this.mSaveButton.setTextColor(getPrimaryTextColor()); - } else if (mAccount != null && (mAccount.getStatus() == Account.State.CONNECTING || mFetchingAvatar)) { + } else if (mAccount != null + && (mAccount.getStatus() == Account.State.CONNECTING || mAccount.getStatus() == Account.State.REGISTRATION_SUCCESSFUL|| mFetchingAvatar)) { this.mSaveButton.setEnabled(false); this.mSaveButton.setTextColor(getSecondaryTextColor()); this.mSaveButton.setText(R.string.account_status_connecting); @@ -536,6 +536,7 @@ public class EditAccountActivity extends XmppActivity implements OnAccountUpdate protected void onBackendConnected() { if (this.jidToEdit != null) { this.mAccount = xmppConnectionService.findAccountByJid(jidToEdit); + this.mInitMode |= this.mAccount.isOptionSet(Account.OPTION_REGISTER); if (this.mAccount != null) { if (this.mAccount.getPrivateKeyAlias() != null) { this.mPassword.setHint(R.string.authenticate_with_certificate); @@ -631,6 +632,8 @@ public class EditAccountActivity extends XmppActivity implements OnAccountUpdate if (!mInitMode) { this.mAvatar.setVisibility(View.VISIBLE); this.mAvatar.setImageBitmap(avatarService().get(this.mAccount, getPixel(72))); + } else { + this.mAvatar.setVisibility(View.GONE); } if (this.mAccount.isOptionSet(Account.OPTION_REGISTER)) { this.mRegisterNew.setVisibility(View.VISIBLE); -- cgit v1.2.3 From 5786e753740065cb2a5398ee964642054074e6f2 Mon Sep 17 00:00:00 2001 From: Daniel Gultsch Date: Sun, 10 Apr 2016 00:19:53 +0200 Subject: don't throw IO exception at end of stream --- src/main/java/eu/siacs/conversations/xmpp/XmppConnection.java | 1 - 1 file changed, 1 deletion(-) (limited to 'src/main/java/eu/siacs') diff --git a/src/main/java/eu/siacs/conversations/xmpp/XmppConnection.java b/src/main/java/eu/siacs/conversations/xmpp/XmppConnection.java index 30cb96dc..7bc08e9c 100644 --- a/src/main/java/eu/siacs/conversations/xmpp/XmppConnection.java +++ b/src/main/java/eu/siacs/conversations/xmpp/XmppConnection.java @@ -560,7 +560,6 @@ public class XmppConnection implements Runnable { } nextTag = tagReader.readTag(); } - throw new IOException("reached end of stream. last tag was "+nextTag); } private void acknowledgeStanzaUpTo(int serverCount) { -- cgit v1.2.3 From 7ff890e513212f1cf03667e4ea7e429431d811c4 Mon Sep 17 00:00:00 2001 From: Daniel Gultsch Date: Mon, 11 Apr 2016 22:20:32 +0200 Subject: republish avatar if server offers non-persistent pep :-( --- .../conversations/persistance/FileBackend.java | 38 ++++++++ .../conversations/services/AvatarService.java | 23 ++++- .../services/XmppConnectionService.java | 104 ++++++++++++++++----- .../siacs/conversations/xmpp/XmppConnection.java | 16 ++-- 4 files changed, 144 insertions(+), 37 deletions(-) (limited to 'src/main/java/eu/siacs') diff --git a/src/main/java/eu/siacs/conversations/persistance/FileBackend.java b/src/main/java/eu/siacs/conversations/persistance/FileBackend.java index 0861a3a8..0d770fef 100644 --- a/src/main/java/eu/siacs/conversations/persistance/FileBackend.java +++ b/src/main/java/eu/siacs/conversations/persistance/FileBackend.java @@ -26,6 +26,7 @@ import java.io.ByteArrayOutputStream; import java.io.Closeable; import java.io.File; import java.io.FileDescriptor; +import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.IOException; @@ -402,6 +403,43 @@ public class FileBackend { } } + public Avatar getStoredPepAvatar(String hash) { + if (hash == null) { + return null; + } + Avatar avatar = new Avatar(); + File file = new File(getAvatarPath(hash)); + FileInputStream is = null; + try { + BitmapFactory.Options options = new BitmapFactory.Options(); + options.inJustDecodeBounds = true; + BitmapFactory.decodeFile(file.getAbsolutePath(), options); + is = new FileInputStream(file); + ByteArrayOutputStream mByteArrayOutputStream = new ByteArrayOutputStream(); + Base64OutputStream mBase64OutputStream = new Base64OutputStream(mByteArrayOutputStream, Base64.DEFAULT); + MessageDigest digest = MessageDigest.getInstance("SHA-1"); + DigestOutputStream os = new DigestOutputStream(mBase64OutputStream, digest); + byte[] buffer = new byte[4096]; + int length; + while ((length = is.read(buffer)) > 0) { + os.write(buffer, 0, length); + } + os.flush(); + os.close(); + avatar.sha1sum = CryptoHelper.bytesToHex(digest.digest()); + avatar.image = new String(mByteArrayOutputStream.toByteArray()); + avatar.height = options.outHeight; + avatar.width = options.outWidth; + return avatar; + } catch (IOException e) { + return null; + } catch (NoSuchAlgorithmException e) { + return null; + } finally { + close(is); + } + } + public boolean isAvatarCached(Avatar avatar) { File file = new File(getAvatarPath(avatar.getFilename())); return file.exists(); diff --git a/src/main/java/eu/siacs/conversations/services/AvatarService.java b/src/main/java/eu/siacs/conversations/services/AvatarService.java index 276be10d..bb8ec5f2 100644 --- a/src/main/java/eu/siacs/conversations/services/AvatarService.java +++ b/src/main/java/eu/siacs/conversations/services/AvatarService.java @@ -6,11 +6,13 @@ import android.graphics.Paint; import android.graphics.Rect; import android.graphics.Typeface; import android.net.Uri; +import android.util.Log; import java.util.ArrayList; import java.util.List; import java.util.Locale; +import eu.siacs.conversations.Config; import eu.siacs.conversations.entities.Account; import eu.siacs.conversations.entities.Bookmark; import eu.siacs.conversations.entities.Contact; @@ -19,8 +21,10 @@ import eu.siacs.conversations.entities.ListItem; import eu.siacs.conversations.entities.Message; import eu.siacs.conversations.entities.MucOptions; import eu.siacs.conversations.utils.UIHelper; +import eu.siacs.conversations.xmpp.OnAdvancedStreamFeaturesLoaded; +import eu.siacs.conversations.xmpp.XmppConnection; -public class AvatarService { +public class AvatarService implements OnAdvancedStreamFeaturesLoaded { private static final int FG_COLOR = 0xFFFAFAFA; private static final int TRANSPARENT = 0x00000000; @@ -227,8 +231,7 @@ public class AvatarService { if (avatar != null || cachedOnly) { return avatar; } - avatar = mXmppConnectionService.getFileBackend().getAvatar( - account.getAvatar(), size); + avatar = mXmppConnectionService.getFileBackend().getAvatar(account.getAvatar(), size); if (avatar == null) { avatar = get(account.getJid().toBareJid().toString(), size,false); } @@ -387,10 +390,20 @@ public class AvatarService { return false; } - private boolean drawTile(Canvas canvas, Bitmap bm, int dstleft, int dsttop, - int dstright, int dstbottom) { + private boolean drawTile(Canvas canvas, Bitmap bm, int dstleft, int dsttop, int dstright, int dstbottom) { Rect dst = new Rect(dstleft, dsttop, dstright, dstbottom); canvas.drawBitmap(bm, null, dst, null); return true; } + + @Override + public void onAdvancedStreamFeaturesAvailable(Account account) { + XmppConnection.Features features = account.getXmppConnection().getFeatures(); + if (features.pep() && !features.pepPersistent()) { + Log.d(Config.LOGTAG,account.getJid().toBareJid()+": has pep but is not persistent"); + if (account.getAvatar() != null) { + mXmppConnectionService.republishAvatarIfNeeded(account); + } + } + } } diff --git a/src/main/java/eu/siacs/conversations/services/XmppConnectionService.java b/src/main/java/eu/siacs/conversations/services/XmppConnectionService.java index 2aaf9b62..117ab861 100644 --- a/src/main/java/eu/siacs/conversations/services/XmppConnectionService.java +++ b/src/main/java/eu/siacs/conversations/services/XmppConnectionService.java @@ -840,6 +840,7 @@ public class XmppConnectionService extends Service implements OnPhoneContactsLoa connection.setOnBindListener(this.mOnBindListener); connection.setOnMessageAcknowledgeListener(this.mOnMessageAcknowledgedListener); connection.addOnAdvancedStreamFeaturesAvailableListener(this.mMessageArchiveService); + connection.addOnAdvancedStreamFeaturesAvailableListener(this.mAvatarService); AxolotlService axolotlService = account.getAxolotlService(); if (axolotlService != null) { connection.addOnAdvancedStreamFeaturesAvailableListener(axolotlService); @@ -2338,9 +2339,7 @@ public class XmppConnectionService extends Service implements OnPhoneContactsLoa } } - public void publishAvatar(final Account account, - final Uri image, - final UiCallback callback) { + public void publishAvatar(Account account, Uri image, UiCallback callback) { final Bitmap.CompressFormat format = Config.AVATAR_FORMAT; final int size = Config.AVATAR_SIZE; final Avatar avatar = getFileBackend().getPepAvatar(image, size, format); @@ -2358,40 +2357,96 @@ public class XmppConnectionService extends Service implements OnPhoneContactsLoa callback.error(R.string.error_saving_avatar, avatar); return; } - final IqPacket packet = this.mIqGenerator.publishAvatar(avatar); - this.sendIqPacket(account, packet, new OnIqPacketReceived() { + publishAvatar(account, avatar, callback); + } else { + callback.error(R.string.error_publish_avatar_converting, null); + } + } - @Override - public void onIqPacketReceived(Account account, IqPacket result) { - if (result.getType() == IqPacket.TYPE.RESULT) { - final IqPacket packet = XmppConnectionService.this.mIqGenerator - .publishAvatarMetadata(avatar); - sendIqPacket(account, packet, new OnIqPacketReceived() { - @Override - public void onIqPacketReceived(Account account, IqPacket result) { - if (result.getType() == IqPacket.TYPE.RESULT) { - if (account.setAvatar(avatar.getFilename())) { - getAvatarService().clear(account); - databaseBackend.updateAccount(account); - } + public void publishAvatar(Account account, final Avatar avatar, final UiCallback callback) { + final IqPacket packet = this.mIqGenerator.publishAvatar(avatar); + this.sendIqPacket(account, packet, new OnIqPacketReceived() { + + @Override + public void onIqPacketReceived(Account account, IqPacket result) { + if (result.getType() == IqPacket.TYPE.RESULT) { + final IqPacket packet = XmppConnectionService.this.mIqGenerator + .publishAvatarMetadata(avatar); + sendIqPacket(account, packet, new OnIqPacketReceived() { + @Override + public void onIqPacketReceived(Account account, IqPacket result) { + if (result.getType() == IqPacket.TYPE.RESULT) { + if (account.setAvatar(avatar.getFilename())) { + getAvatarService().clear(account); + databaseBackend.updateAccount(account); + } + if (callback != null) { callback.success(avatar); } else { + Log.d(Config.LOGTAG,account.getJid().toBareJid()+": published avatar"); + } + } else { + if (callback != null) { callback.error( R.string.error_publish_avatar_server_reject, avatar); } } - }); - } else { + } + }); + } else { + if (callback != null) { callback.error( R.string.error_publish_avatar_server_reject, avatar); } } - }); - } else { - callback.error(R.string.error_publish_avatar_converting, null); + } + }); + } + + public void republishAvatarIfNeeded(Account account) { + if (account.getAxolotlService().isPepBroken()) { + Log.d(Config.LOGTAG,account.getJid().toBareJid()+": skipping republication of avatar because pep is broken"); + return; } + IqPacket packet = this.mIqGenerator.retrieveAvatarMetaData(null); + this.sendIqPacket(account, packet, new OnIqPacketReceived() { + + private Avatar parseAvatar(IqPacket packet) { + Element pubsub = packet.findChild("pubsub", "http://jabber.org/protocol/pubsub"); + if (pubsub != null) { + Element items = pubsub.findChild("items"); + if (items != null) { + return Avatar.parseMetadata(items); + } + } + return null; + } + + private boolean errorIsItemNotFound(IqPacket packet) { + Element error = packet.findChild("error"); + return packet.getType() == IqPacket.TYPE.ERROR + && error != null + && error.hasChild("item-not-found"); + } + + @Override + public void onIqPacketReceived(Account account, IqPacket packet) { + if (packet.getType() == IqPacket.TYPE.RESULT || errorIsItemNotFound(packet)) { + Avatar serverAvatar = parseAvatar(packet); + if (serverAvatar == null && account.getAvatar() != null) { + Avatar avatar = fileBackend.getStoredPepAvatar(account.getAvatar()); + if (avatar != null) { + Log.d(Config.LOGTAG,account.getJid().toBareJid()+": avatar on server was null. republishing"); + publishAvatar(account, fileBackend.getStoredPepAvatar(account.getAvatar()), null); + } else { + Log.e(Config.LOGTAG, account.getJid().toBareJid()+": error rereading avatar"); + } + } + } + } + }); } public void fetchAvatar(Account account, Avatar avatar) { @@ -2526,8 +2581,7 @@ public class XmppConnectionService extends Service implements OnPhoneContactsLoa @Override public void onIqPacketReceived(Account account, IqPacket packet) { 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) { Element items = pubsub.findChild("items"); if (items != null) { diff --git a/src/main/java/eu/siacs/conversations/xmpp/XmppConnection.java b/src/main/java/eu/siacs/conversations/xmpp/XmppConnection.java index 7bc08e9c..4dc5492e 100644 --- a/src/main/java/eu/siacs/conversations/xmpp/XmppConnection.java +++ b/src/main/java/eu/siacs/conversations/xmpp/XmppConnection.java @@ -1530,13 +1530,15 @@ public class XmppConnection implements Runnable { public boolean pep() { synchronized (XmppConnection.this.disco) { - ServiceDiscoveryResult info = disco.get(account.getServer()); - if (info != null && info.hasIdentity("pubsub", "pep")) { - return true; - } else { - info = disco.get(account.getJid().toBareJid()); - return info != null && info.hasIdentity("pubsub", "pep"); - } + ServiceDiscoveryResult info = disco.get(account.getJid().toBareJid()); + return info != null && info.hasIdentity("pubsub", "pep"); + } + } + + public boolean pepPersistent() { + synchronized (XmppConnection.this.disco) { + ServiceDiscoveryResult info = disco.get(account.getJid().toBareJid()); + return info != null && info.getFeatures().contains("http://jabber.org/protocol/pubsub#persistent-items"); } } -- cgit v1.2.3 From 7223b5b2746c2250c94965f89d9f636017e447da Mon Sep 17 00:00:00 2001 From: Daniel Gultsch Date: Tue, 12 Apr 2016 17:52:58 +0200 Subject: minor code cleanup --- .../java/eu/siacs/conversations/services/XmppConnectionService.java | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) (limited to 'src/main/java/eu/siacs') diff --git a/src/main/java/eu/siacs/conversations/services/XmppConnectionService.java b/src/main/java/eu/siacs/conversations/services/XmppConnectionService.java index 117ab861..0c4e5f62 100644 --- a/src/main/java/eu/siacs/conversations/services/XmppConnectionService.java +++ b/src/main/java/eu/siacs/conversations/services/XmppConnectionService.java @@ -2456,9 +2456,7 @@ public class XmppConnectionService extends Service implements OnPhoneContactsLoa public void fetchAvatar(Account account, final Avatar avatar, final UiCallback callback) { final String KEY = generateFetchKey(account, avatar); synchronized (this.mInProgressAvatarFetches) { - if (this.mInProgressAvatarFetches.contains(KEY)) { - return; - } else { + if (!this.mInProgressAvatarFetches.contains(KEY)) { switch (avatar.origin) { case PEP: this.mInProgressAvatarFetches.add(KEY); -- cgit v1.2.3 From 2a4db01709909c385808f9a42dd9251f9836eed1 Mon Sep 17 00:00:00 2001 From: Daniel Gultsch Date: Tue, 12 Apr 2016 18:29:41 +0200 Subject: reverse order in contact chooser --- .../eu/siacs/conversations/services/ContactChooserTargetService.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/main/java/eu/siacs') diff --git a/src/main/java/eu/siacs/conversations/services/ContactChooserTargetService.java b/src/main/java/eu/siacs/conversations/services/ContactChooserTargetService.java index c2a45bf2..0a8ac98c 100644 --- a/src/main/java/eu/siacs/conversations/services/ContactChooserTargetService.java +++ b/src/main/java/eu/siacs/conversations/services/ContactChooserTargetService.java @@ -52,7 +52,7 @@ public class ContactChooserTargetService extends ChooserTargetService implements final Conversation conversation = conversations.get(i); final String name = conversation.getName(); final Icon icon = Icon.createWithBitmap(mXmppConnectionService.getAvatarService().get(conversation, pixel)); - final float score = (1.0f / MAX_TARGETS) * i; + final float score = 1 - (1.0f / MAX_TARGETS) * i; final Bundle extras = new Bundle(); extras.putString("uuid", conversation.getUuid()); chooserTargets.add(new ChooserTarget(name, icon, score, componentName, extras)); -- cgit v1.2.3 From 3e654bea0e26616b11166a37bbf7822aef25d2f0 Mon Sep 17 00:00:00 2001 From: Daniel Gultsch Date: Tue, 12 Apr 2016 18:30:02 +0200 Subject: added share uri button to conference details --- .../conversations/ui/ConferenceDetailsActivity.java | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) (limited to 'src/main/java/eu/siacs') diff --git a/src/main/java/eu/siacs/conversations/ui/ConferenceDetailsActivity.java b/src/main/java/eu/siacs/conversations/ui/ConferenceDetailsActivity.java index adbb0953..a2757070 100644 --- a/src/main/java/eu/siacs/conversations/ui/ConferenceDetailsActivity.java +++ b/src/main/java/eu/siacs/conversations/ui/ConferenceDetailsActivity.java @@ -3,8 +3,10 @@ package eu.siacs.conversations.ui; import android.annotation.TargetApi; import android.app.AlertDialog; import android.app.PendingIntent; +import android.content.ActivityNotFoundException; import android.content.Context; import android.content.DialogInterface; +import android.content.Intent; import android.content.IntentSender.SendIntentException; import android.os.Build; import android.os.Bundle; @@ -281,6 +283,9 @@ public class ConferenceDetailsActivity extends XmppActivity implements OnConvers quickEdit(mConversation.getName(),this.onSubjectEdited); } break; + case R.id.action_share: + share(); + break; case R.id.action_save_as_bookmark: saveAsBookmark(); break; @@ -308,6 +313,18 @@ public class ConferenceDetailsActivity extends XmppActivity implements OnConvers } } + private void share() { + Intent shareIntent = new Intent(); + shareIntent.setAction(Intent.ACTION_SEND); + shareIntent.putExtra(Intent.EXTRA_TEXT, getShareableUri()); + shareIntent.setType("text/plain"); + try { + startActivity(Intent.createChooser(shareIntent, getText(R.string.share_uri_with))); + } catch (ActivityNotFoundException e) { + Toast.makeText(this, R.string.no_application_to_share_uri, Toast.LENGTH_SHORT).show(); + } + } + @Override public boolean onPrepareOptionsMenu(Menu menu) { MenuItem menuItemSaveBookmark = menu.findItem(R.id.action_save_as_bookmark); -- cgit v1.2.3 From 4332b0df44bb6345b0fbb861d1bb8d24568ea847 Mon Sep 17 00:00:00 2001 From: Daniel Gultsch Date: Wed, 13 Apr 2016 11:13:47 +0200 Subject: return own jid as true counterpart on self messages in muc --- src/main/java/eu/siacs/conversations/entities/MucOptions.java | 3 +++ 1 file changed, 3 insertions(+) (limited to 'src/main/java/eu/siacs') diff --git a/src/main/java/eu/siacs/conversations/entities/MucOptions.java b/src/main/java/eu/siacs/conversations/entities/MucOptions.java index db27810f..7681a3d4 100644 --- a/src/main/java/eu/siacs/conversations/entities/MucOptions.java +++ b/src/main/java/eu/siacs/conversations/entities/MucOptions.java @@ -469,6 +469,9 @@ public class MucOptions { } public Jid getTrueCounterpart(String name) { + if (name.equals(getSelf().getName())) { + return account.getJid().toBareJid(); + } User user = findUser(name); return user == null ? null : user.getJid(); } -- cgit v1.2.3 From 594e65bb2b26d1c99b96c12558bf9d523e68269e Mon Sep 17 00:00:00 2001 From: Daniel Gultsch Date: Wed, 13 Apr 2016 11:14:36 +0200 Subject: hacky workaround to determine if uri points to private file on < lolipop --- .../conversations/persistance/FileBackend.java | 26 +++++++++++++++++----- .../services/XmppConnectionService.java | 4 ++-- .../ui/PublishProfilePictureActivity.java | 4 ++-- 3 files changed, 25 insertions(+), 9 deletions(-) (limited to 'src/main/java/eu/siacs') diff --git a/src/main/java/eu/siacs/conversations/persistance/FileBackend.java b/src/main/java/eu/siacs/conversations/persistance/FileBackend.java index 0d770fef..30609214 100644 --- a/src/main/java/eu/siacs/conversations/persistance/FileBackend.java +++ b/src/main/java/eu/siacs/conversations/persistance/FileBackend.java @@ -693,13 +693,29 @@ public class FileBackend { } - public static boolean weOwnFile(Uri uri) { - if (Build.VERSION.SDK_INT < Build.VERSION_CODES.LOLLIPOP) { + public static boolean weOwnFile(Context context, Uri uri) { + if (uri == null || !ContentResolver.SCHEME_FILE.equals(uri.getScheme())) { return false; + } else if (Build.VERSION.SDK_INT < Build.VERSION_CODES.LOLLIPOP) { + return fileIsInFilesDir(context, uri); } else { - return uri != null - && ContentResolver.SCHEME_FILE.equals(uri.getScheme()) - && weOwnFileLollipop(uri); + return weOwnFileLollipop(uri); + } + } + + + /** + * This is more than hacky but probably way better than doing nothing + * Further 'optimizations' might contain to get the parents of CacheDir and NoBackupDir + * and check against those as well + */ + private static boolean fileIsInFilesDir(Context context, Uri uri) { + try { + final String haystack = context.getFilesDir().getParentFile().getCanonicalPath(); + final String needle = new File(uri.getPath()).getCanonicalPath(); + return needle.startsWith(haystack); + } catch (IOException e) { + return false; } } diff --git a/src/main/java/eu/siacs/conversations/services/XmppConnectionService.java b/src/main/java/eu/siacs/conversations/services/XmppConnectionService.java index 0c4e5f62..61d78409 100644 --- a/src/main/java/eu/siacs/conversations/services/XmppConnectionService.java +++ b/src/main/java/eu/siacs/conversations/services/XmppConnectionService.java @@ -403,7 +403,7 @@ public class XmppConnectionService extends Service implements OnPhoneContactsLoa public void attachFileToConversation(final Conversation conversation, final Uri uri, final UiCallback callback) { - if (FileBackend.weOwnFile(uri)) { + if (FileBackend.weOwnFile(this, uri)) { Log.d(Config.LOGTAG,"trying to attach file that belonged to us"); callback.error(R.string.security_error_invalid_file_access, null); return; @@ -446,7 +446,7 @@ public class XmppConnectionService extends Service implements OnPhoneContactsLoa } public void attachImageToConversation(final Conversation conversation, final Uri uri, final UiCallback callback) { - if (FileBackend.weOwnFile(uri)) { + if (FileBackend.weOwnFile(this, uri)) { Log.d(Config.LOGTAG,"trying to attach file that belonged to us"); callback.error(R.string.security_error_invalid_file_access, null); return; diff --git a/src/main/java/eu/siacs/conversations/ui/PublishProfilePictureActivity.java b/src/main/java/eu/siacs/conversations/ui/PublishProfilePictureActivity.java index 27a3efe5..0752ae32 100644 --- a/src/main/java/eu/siacs/conversations/ui/PublishProfilePictureActivity.java +++ b/src/main/java/eu/siacs/conversations/ui/PublishProfilePictureActivity.java @@ -191,7 +191,7 @@ public class PublishProfilePictureActivity extends XmppActivity { Uri source = data.getData(); switch (requestCode) { case REQUEST_CHOOSE_FILE_AND_CROP: - if (FileBackend.weOwnFile(source)) { + if (FileBackend.weOwnFile(this, source)) { Toast.makeText(this,R.string.security_error_invalid_file_access,Toast.LENGTH_SHORT).show(); return; } @@ -204,7 +204,7 @@ public class PublishProfilePictureActivity extends XmppActivity { Crop.of(source, destination).asSquare().withMaxSize(size, size).start(this); break; case REQUEST_CHOOSE_FILE: - if (FileBackend.weOwnFile(source)) { + if (FileBackend.weOwnFile(this, source)) { Toast.makeText(this,R.string.security_error_invalid_file_access,Toast.LENGTH_SHORT).show(); return; } -- cgit v1.2.3 From c53c6cb6b60a575fb40746d840b80f8781a9bfab Mon Sep 17 00:00:00 2001 From: Daniel Gultsch Date: Wed, 13 Apr 2016 18:00:12 +0200 Subject: create Config varibale to show the disable foreground service button --- src/main/java/eu/siacs/conversations/Config.java | 1 + .../java/eu/siacs/conversations/services/NotificationService.java | 8 +++++--- 2 files changed, 6 insertions(+), 3 deletions(-) (limited to 'src/main/java/eu/siacs') diff --git a/src/main/java/eu/siacs/conversations/Config.java b/src/main/java/eu/siacs/conversations/Config.java index e39cd654..55fff255 100644 --- a/src/main/java/eu/siacs/conversations/Config.java +++ b/src/main/java/eu/siacs/conversations/Config.java @@ -48,6 +48,7 @@ public final class Config { public static final boolean FORCE_ORBOT = false; // always use TOR public static final boolean HIDE_MESSAGE_TEXT_IN_NOTIFICATION = false; public static final boolean SHOW_CONNECTED_ACCOUNTS = false; //show number of connected accounts in foreground notification + public static final boolean SHOW_DISABLE_FOREGROUND = true; //if set to true the foreground notification has a button to disable it public static final boolean ALWAYS_NOTIFY_BY_DEFAULT = false; diff --git a/src/main/java/eu/siacs/conversations/services/NotificationService.java b/src/main/java/eu/siacs/conversations/services/NotificationService.java index 003f5471..764a1d52 100644 --- a/src/main/java/eu/siacs/conversations/services/NotificationService.java +++ b/src/main/java/eu/siacs/conversations/services/NotificationService.java @@ -544,9 +544,11 @@ public class NotificationService { cancelIcon = R.drawable.ic_action_cancel; } mBuilder.setSmallIcon(R.drawable.ic_link_white_24dp); - mBuilder.addAction(cancelIcon, - mXmppConnectionService.getString(R.string.disable_foreground_service), - createDisableForeground()); + if (Config.SHOW_DISABLE_FOREGROUND) { + mBuilder.addAction(cancelIcon, + mXmppConnectionService.getString(R.string.disable_foreground_service), + createDisableForeground()); + } return mBuilder.build(); } -- cgit v1.2.3 From 39e717ed94de2800df587395ba77310660c2ea5c Mon Sep 17 00:00:00 2001 From: Daniel Gultsch Date: Thu, 14 Apr 2016 00:16:59 +0200 Subject: removed unused call to cancel events --- src/main/java/eu/siacs/conversations/services/XmppConnectionService.java | 1 - 1 file changed, 1 deletion(-) (limited to 'src/main/java/eu/siacs') diff --git a/src/main/java/eu/siacs/conversations/services/XmppConnectionService.java b/src/main/java/eu/siacs/conversations/services/XmppConnectionService.java index 61d78409..a975bf4d 100644 --- a/src/main/java/eu/siacs/conversations/services/XmppConnectionService.java +++ b/src/main/java/eu/siacs/conversations/services/XmppConnectionService.java @@ -801,7 +801,6 @@ public class XmppConnectionService extends Service implements OnPhoneContactsLoa disconnect(account, false); } }).start(); - cancelWakeUpCall(account.getUuid().hashCode()); } } Log.d(Config.LOGTAG, "good bye"); -- cgit v1.2.3 From 72aa10b53660fdb6e32f74a103ff1e349232a816 Mon Sep 17 00:00:00 2001 From: Daniel Gultsch Date: Thu, 14 Apr 2016 21:12:44 +0200 Subject: add setting for quick sharing --- .../siacs/conversations/ui/ShareWithActivity.java | 27 ++++++++++++++++++++-- 1 file changed, 25 insertions(+), 2 deletions(-) (limited to 'src/main/java/eu/siacs') diff --git a/src/main/java/eu/siacs/conversations/ui/ShareWithActivity.java b/src/main/java/eu/siacs/conversations/ui/ShareWithActivity.java index 8cd017bf..4ed015f4 100644 --- a/src/main/java/eu/siacs/conversations/ui/ShareWithActivity.java +++ b/src/main/java/eu/siacs/conversations/ui/ShareWithActivity.java @@ -32,6 +32,8 @@ import eu.siacs.conversations.xmpp.jid.Jid; public class ShareWithActivity extends XmppActivity implements XmppConnectionService.OnConversationUpdate { + private boolean mReturnToPrevious = false; + @Override public void onConversationUpdate() { refreshUi(); @@ -80,7 +82,7 @@ public class ShareWithActivity extends XmppActivity implements XmppConnectionSer resId = R.string.shared_file_with_x; } replaceToast(getString(resId, message.getConversation().getName())); - if (share.uuid != null) { + if (mReturnToPrevious) { finish(); } else { switchToConversation(message.getConversation()); @@ -181,6 +183,7 @@ public class ShareWithActivity extends XmppActivity implements XmppConnectionSer if (intent == null) { return; } + this.mReturnToPrevious = getPreferences().getBoolean("return_to_previous", false); final String type = intent.getType(); final String action = intent.getAction(); Log.d(Config.LOGTAG, "action: "+action+ ", type:"+type); @@ -305,7 +308,27 @@ public class ShareWithActivity extends XmppActivity implements XmppConnectionSer selectPresence(conversation, callback); } } else { - switchToConversation(conversation, this.share.text, true); + if (mReturnToPrevious && this.share.text != null && !this.share.text.isEmpty() ) { + final OnPresenceSelected callback = new OnPresenceSelected() { + @Override + public void onPresenceSelected() { + Message message = new Message(conversation,share.text, conversation.getNextEncryption()); + if (conversation.getNextEncryption() == Message.ENCRYPTION_OTR) { + message.setCounterpart(conversation.getNextCounterpart()); + } + xmppConnectionService.sendMessage(message); + replaceToast(getString(R.string.shared_text_with_x, conversation.getName())); + finish(); + } + }; + if (conversation.getNextEncryption() == Message.ENCRYPTION_OTR) { + selectPresence(conversation, callback); + } else { + callback.onPresenceSelected(); + } + } else { + switchToConversation(conversation, this.share.text, true); + } } } -- cgit v1.2.3 From eb63cdb9adcf6b0324898fc45d8bdbad964a1892 Mon Sep 17 00:00:00 2001 From: Daniel Gultsch Date: Thu, 14 Apr 2016 21:45:36 +0200 Subject: removed unnecessary call to stopSelf() after logging out --- .../conversations/services/XmppConnectionService.java | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) (limited to 'src/main/java/eu/siacs') diff --git a/src/main/java/eu/siacs/conversations/services/XmppConnectionService.java b/src/main/java/eu/siacs/conversations/services/XmppConnectionService.java index a975bf4d..dbfb818d 100644 --- a/src/main/java/eu/siacs/conversations/services/XmppConnectionService.java +++ b/src/main/java/eu/siacs/conversations/services/XmppConnectionService.java @@ -509,7 +509,7 @@ public class XmppConnectionService extends Service implements OnPhoneContactsLoa } return START_STICKY; case Intent.ACTION_SHUTDOWN: - logoutAndSave(); + logoutAndSave(true); return START_NOT_STICKY; case ACTION_CLEAR_NOTIFICATION: mNotificationService.clear(); @@ -787,12 +787,16 @@ public class XmppConnectionService extends Service implements OnPhoneContactsLoa public void onTaskRemoved(final Intent rootIntent) { super.onTaskRemoved(rootIntent); if (!getPreferences().getBoolean("keep_foreground_service", false)) { - this.logoutAndSave(); + this.logoutAndSave(false); } } - private void logoutAndSave() { + private void logoutAndSave(boolean stop) { + int activeAccounts = 0; for (final Account account : accounts) { + if (account.getStatus() != Account.State.DISABLED) { + activeAccounts++; + } databaseBackend.writeRoster(account.getRoster()); if (account.getXmppConnection() != null) { new Thread(new Runnable() { @@ -803,8 +807,10 @@ public class XmppConnectionService extends Service implements OnPhoneContactsLoa }).start(); } } - Log.d(Config.LOGTAG, "good bye"); - stopSelf(); + if (stop || activeAccounts == 0) { + Log.d(Config.LOGTAG, "good bye"); + stopSelf(); + } } private void cancelWakeUpCall(int requestCode) { -- cgit v1.2.3 From e9494af098e6d3dad4f0a5328ae7342664ce853c Mon Sep 17 00:00:00 2001 From: Daniel Gultsch Date: Thu, 14 Apr 2016 22:37:05 +0200 Subject: always notify by default in conferences --- src/main/java/eu/siacs/conversations/Config.java | 2 -- src/main/java/eu/siacs/conversations/entities/Conversation.java | 2 +- 2 files changed, 1 insertion(+), 3 deletions(-) (limited to 'src/main/java/eu/siacs') diff --git a/src/main/java/eu/siacs/conversations/Config.java b/src/main/java/eu/siacs/conversations/Config.java index 55fff255..bfbf9a7f 100644 --- a/src/main/java/eu/siacs/conversations/Config.java +++ b/src/main/java/eu/siacs/conversations/Config.java @@ -50,8 +50,6 @@ public final class Config { public static final boolean SHOW_CONNECTED_ACCOUNTS = false; //show number of connected accounts in foreground notification public static final boolean SHOW_DISABLE_FOREGROUND = true; //if set to true the foreground notification has a button to disable it - public static final boolean ALWAYS_NOTIFY_BY_DEFAULT = false; - public static final boolean LEGACY_NAMESPACE_HTTP_UPLOAD = false; public static final int PING_MAX_INTERVAL = 300; diff --git a/src/main/java/eu/siacs/conversations/entities/Conversation.java b/src/main/java/eu/siacs/conversations/entities/Conversation.java index a3ae906b..b1d597df 100644 --- a/src/main/java/eu/siacs/conversations/entities/Conversation.java +++ b/src/main/java/eu/siacs/conversations/entities/Conversation.java @@ -809,7 +809,7 @@ public class Conversation extends AbstractEntity implements Blockable { } public boolean alwaysNotify() { - return mode == MODE_SINGLE || getBooleanAttribute(ATTRIBUTE_ALWAYS_NOTIFY, Config.ALWAYS_NOTIFY_BY_DEFAULT || isPnNA()); + return mode == MODE_SINGLE || getBooleanAttribute(ATTRIBUTE_ALWAYS_NOTIFY, true); } public boolean setAttribute(String key, String value) { -- cgit v1.2.3