From efdf3b6c1ca0fe807781a2e974d42f8853599f9b Mon Sep 17 00:00:00 2001 From: Daniel Gultsch Date: Sat, 8 Aug 2015 13:13:23 +0200 Subject: removed dead code --- src/main/java/eu/siacs/conversations/xmpp/XmppConnection.java | 10 ---------- 1 file changed, 10 deletions(-) (limited to 'src/main') diff --git a/src/main/java/eu/siacs/conversations/xmpp/XmppConnection.java b/src/main/java/eu/siacs/conversations/xmpp/XmppConnection.java index bf89ba816..5ac089766 100644 --- a/src/main/java/eu/siacs/conversations/xmpp/XmppConnection.java +++ b/src/main/java/eu/siacs/conversations/xmpp/XmppConnection.java @@ -81,7 +81,6 @@ public class XmppConnection implements Runnable { private static final int PACKET_IQ = 0; private static final int PACKET_MESSAGE = 1; private static final int PACKET_PRESENCE = 2; - private final Context applicationContext; protected Account account; private final WakeLock wakeLock; private Socket socket; @@ -123,7 +122,6 @@ public class XmppConnection implements Runnable { PowerManager.PARTIAL_WAKE_LOCK, account.getJid().toBareJid().toString()); tagWriter = new TagWriter(); mXmppConnectionService = service; - applicationContext = service.getApplicationContext(); } protected void changeStatus(final Account.State nextStatus) { @@ -531,14 +529,6 @@ public class XmppConnection implements Runnable { tagWriter.writeTag(startTLS); } - private SharedPreferences getPreferences() { - return PreferenceManager.getDefaultSharedPreferences(applicationContext); - } - - private boolean enableLegacySSL() { - return getPreferences().getBoolean("enable_legacy_ssl", false); - } - private void switchOverToTls(final Tag currentTag) throws XmlPullParserException, IOException { tagReader.readTag(); try { -- cgit v1.2.3 From 8b9b74ff7ee863160e0cf2827e2a5a431d4fb90f Mon Sep 17 00:00:00 2001 From: Daniel Gultsch Date: Sat, 8 Aug 2015 13:29:21 +0200 Subject: renamed multi-end / axolotl to OMEMO --- src/main/AndroidManifest.xml | 2 +- .../conversations/ui/ConversationFragment.java | 2 +- .../conversations/ui/EditAccountActivity.java | 4 ++-- .../siacs/conversations/ui/TrustKeysActivity.java | 2 +- .../eu/siacs/conversations/ui/XmppActivity.java | 6 +++--- src/main/res/layout/activity_edit_account.xml | 6 +++--- src/main/res/menu/encryption_choices.xml | 6 +++--- src/main/res/values/strings.xml | 23 +++++++++++----------- 8 files changed, 25 insertions(+), 26 deletions(-) (limited to 'src/main') diff --git a/src/main/AndroidManifest.xml b/src/main/AndroidManifest.xml index b0611f848..15d5bc255 100644 --- a/src/main/AndroidManifest.xml +++ b/src/main/AndroidManifest.xml @@ -132,7 +132,7 @@ + android:text="@string/this_device_omemo_fingerprint"/> + android:contentDescription="@string/copy_omemo_clipboard_description"/> + android:contentDescription="@string/regenerate_omemo_key"/> diff --git a/src/main/res/menu/encryption_choices.xml b/src/main/res/menu/encryption_choices.xml index 1b3fe76ef..9af2cd346 100644 --- a/src/main/res/menu/encryption_choices.xml +++ b/src/main/res/menu/encryption_choices.xml @@ -5,15 +5,15 @@ + - \ No newline at end of file diff --git a/src/main/res/values/strings.xml b/src/main/res/values/strings.xml index 41e1ccff2..50c0ecf85 100644 --- a/src/main/res/values/strings.xml +++ b/src/main/res/values/strings.xml @@ -80,7 +80,7 @@ Choose presence to contact Send plain text message Send OTR encrypted message - Send Multi-End encrypted message + Send OMEMO encrypted message Send OpenPGP encrypted message Your nickname has been changed Send unencrypted @@ -155,7 +155,7 @@ Plain text OTR OpenPGP - Multi-End + OMEMO Edit account Delete account Temporarily disable @@ -208,14 +208,13 @@ Reception failed Your fingerprint OTR fingerprint - Multi-End fingerprint - Multi-End fingerprint of message - Own Multi-End fingerprint + OMEMO fingerprint + OMEMO fingerprint of message + Own OMEMO fingerprint Other devices - Trust Multi-End Keys + Trust OMEMO Fingerprints Fetching keys... Done - Other own Multi-End Devices Verify Decrypt Conferences @@ -322,7 +321,7 @@ Conference name Use room’s subject instead of JID to identify conferences OTR fingerprint copied to clipboard! - Multi-End fingerprint copied to clipboard! + OMEMO fingerprint copied to clipboard! You are banned from this conference This conference is members only You have been kicked from this conference @@ -389,11 +388,11 @@ Reset Account avatar Copy OTR fingerprint to clipboard - Copy Multi-End fingerprint to clipboard - Copy Axolotl fingerprint to clipboard - Wipe other devices from PEP + Copy OMEMO fingerprint to clipboard + Regenerate OMEMO key + Wipe other devices from PEP Clear devices - Are you sure you want to clear all other devices from the Multi-End announcement? The next time your devices connect, they will reannounce themselves, but they might not receive messages sent in the meantime. + Are you sure you want to clear all other devices from the OMEMO announcement? The next time your devices connect, they will reannounce themselves, but they might not receive messages sent in the meantime. Purge key Are you sure you want to purge this key? It will irreversibly be considered compromised, and you can never build a session with it again. -- cgit v1.2.3 From a6e00837af31a7671013b5fe007008db55b4c84c Mon Sep 17 00:00:00 2001 From: Daniel Gultsch Date: Sat, 8 Aug 2015 14:09:02 +0200 Subject: decreased right hand side padding in contact keys --- src/main/res/layout/contact_key.xml | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'src/main') diff --git a/src/main/res/layout/contact_key.xml b/src/main/res/layout/contact_key.xml index 0f61a15f1..a4fd29e97 100644 --- a/src/main/res/layout/contact_key.xml +++ b/src/main/res/layout/contact_key.xml @@ -8,7 +8,9 @@ android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignParentLeft="true" - android:padding="8dp" > + android:paddingTop="8dp" + android:paddingLeft="8dp" + android:paddingBottom="8dp"> Date: Sat, 8 Aug 2015 17:19:40 +0200 Subject: fixed image preview in notfications for images that arrived over jingle --- .../eu/siacs/conversations/xmpp/jingle/JingleConnection.java | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) (limited to 'src/main') diff --git a/src/main/java/eu/siacs/conversations/xmpp/jingle/JingleConnection.java b/src/main/java/eu/siacs/conversations/xmpp/jingle/JingleConnection.java index e9ca66b7c..29aafccef 100644 --- a/src/main/java/eu/siacs/conversations/xmpp/jingle/JingleConnection.java +++ b/src/main/java/eu/siacs/conversations/xmpp/jingle/JingleConnection.java @@ -97,15 +97,13 @@ public class JingleConnection implements Transferable { public void onFileTransmitted(DownloadableFile file) { if (responder.equals(account.getJid())) { sendSuccess(); + mXmppConnectionService.getFileBackend().updateFileParams(message); + mXmppConnectionService.databaseBackend.createMessage(message); + mXmppConnectionService.markMessage(message,Message.STATUS_RECEIVED); if (acceptedAutomatically) { message.markUnread(); - JingleConnection.this.mXmppConnectionService - .getNotificationService().push(message); + JingleConnection.this.mXmppConnectionService.getNotificationService().push(message); } - mXmppConnectionService.getFileBackend().updateFileParams(message); - mXmppConnectionService.databaseBackend.createMessage(message); - mXmppConnectionService.markMessage(message, - Message.STATUS_RECEIVED); } else { if (message.getEncryption() == Message.ENCRYPTION_PGP || message.getEncryption() == Message.ENCRYPTION_DECRYPTED) { file.delete(); -- cgit v1.2.3 From b5e90850d88d3fe29387697b8976b52e2e35b1f6 Mon Sep 17 00:00:00 2001 From: Daniel Gultsch Date: Mon, 10 Aug 2015 12:15:14 +0200 Subject: provide more detailed error toasts for http file download --- .../conversations/http/HttpDownloadConnection.java | 95 +++++++++++++--------- src/main/res/values/strings.xml | 4 +- 2 files changed, 61 insertions(+), 38 deletions(-) (limited to 'src/main') diff --git a/src/main/java/eu/siacs/conversations/http/HttpDownloadConnection.java b/src/main/java/eu/siacs/conversations/http/HttpDownloadConnection.java index 79e4654be..0c1ea5034 100644 --- a/src/main/java/eu/siacs/conversations/http/HttpDownloadConnection.java +++ b/src/main/java/eu/siacs/conversations/http/HttpDownloadConnection.java @@ -6,6 +6,7 @@ import android.util.Log; import java.io.BufferedInputStream; import java.io.IOException; +import java.io.InputStream; import java.io.OutputStream; import java.net.HttpURLConnection; import java.net.MalformedURLException; @@ -125,6 +126,17 @@ public class HttpDownloadConnection implements Transferable { mXmppConnectionService.updateConversationUi(); } + private void showToastForException(Exception e) { + e.printStackTrace(); + if (e instanceof java.net.UnknownHostException) { + mXmppConnectionService.showErrorToastInUi(R.string.download_failed_server_not_found); + } else if (e instanceof java.net.ConnectException) { + mXmppConnectionService.showErrorToastInUi(R.string.download_failed_could_not_connect); + } else { + mXmppConnectionService.showErrorToastInUi(R.string.download_failed_file_not_found); + } + } + private class FileSizeChecker implements Runnable { private boolean interactive = false; @@ -146,7 +158,7 @@ public class HttpDownloadConnection implements Transferable { } catch (IOException e) { Log.d(Config.LOGTAG, "io exception in http file size checker: " + e.getMessage()); if (interactive) { - mXmppConnectionService.showErrorToastInUi(R.string.file_not_found_on_remote_host); + showToastForException(e); } cancel(); return; @@ -163,20 +175,23 @@ public class HttpDownloadConnection implements Transferable { } private long retrieveFileSize() throws IOException { - Log.d(Config.LOGTAG,"retrieve file size. interactive:"+String.valueOf(interactive)); - changeStatus(STATUS_CHECKING); - HttpURLConnection connection = (HttpURLConnection) mUrl.openConnection(); - connection.setRequestMethod("HEAD"); - if (connection instanceof HttpsURLConnection) { - mHttpConnectionManager.setupTrustManager((HttpsURLConnection) connection, interactive); - } - connection.connect(); - String contentLength = connection.getHeaderField("Content-Length"); - if (contentLength == null) { - throw new IOException(); - } try { + Log.d(Config.LOGTAG, "retrieve file size. interactive:" + String.valueOf(interactive)); + changeStatus(STATUS_CHECKING); + HttpURLConnection connection = (HttpURLConnection) mUrl.openConnection(); + connection.setRequestMethod("HEAD"); + if (connection instanceof HttpsURLConnection) { + mHttpConnectionManager.setupTrustManager((HttpsURLConnection) connection, interactive); + } + connection.connect(); + String contentLength = connection.getHeaderField("Content-Length"); + connection.disconnect(); + if (contentLength == null) { + throw new IOException(); + } return Long.parseLong(contentLength, 10); + } catch (IOException e) { + throw e; } catch (NumberFormatException e) { throw new IOException(); } @@ -202,37 +217,43 @@ public class HttpDownloadConnection implements Transferable { updateImageBounds(); finish(); } catch (SSLHandshakeException e) { - FileBackend.close(os); changeStatus(STATUS_OFFER); } catch (IOException e) { - FileBackend.close(os); - mXmppConnectionService.showErrorToastInUi(R.string.file_not_found_on_remote_host); + if (interactive) { + showToastForException(e); + } cancel(); } } - private void download() throws IOException { - HttpURLConnection connection = (HttpURLConnection) mUrl.openConnection(); - if (connection instanceof HttpsURLConnection) { - mHttpConnectionManager.setupTrustManager((HttpsURLConnection) connection, interactive); - } - connection.connect(); - BufferedInputStream is = new BufferedInputStream(connection.getInputStream()); - file.getParentFile().mkdirs(); - file.createNewFile(); - os = AbstractConnectionManager.createOutputStream(file,true); - long transmitted = 0; - long expected = file.getExpectedSize(); - int count = -1; - byte[] buffer = new byte[1024]; - while ((count = is.read(buffer)) != -1) { - transmitted += count; - os.write(buffer, 0, count); - updateProgress((int) ((((double) transmitted) / expected) * 100)); + private void download() throws IOException { + InputStream is = null; + try { + HttpURLConnection connection = (HttpURLConnection) mUrl.openConnection(); + if (connection instanceof HttpsURLConnection) { + mHttpConnectionManager.setupTrustManager((HttpsURLConnection) connection, interactive); + } + connection.connect(); + is = new BufferedInputStream(connection.getInputStream()); + file.getParentFile().mkdirs(); + file.createNewFile(); + os = AbstractConnectionManager.createOutputStream(file, true); + long transmitted = 0; + long expected = file.getExpectedSize(); + int count = -1; + byte[] buffer = new byte[1024]; + while ((count = is.read(buffer)) != -1) { + transmitted += count; + os.write(buffer, 0, count); + updateProgress((int) ((((double) transmitted) / expected) * 100)); + } + os.flush(); + } catch (IOException e) { + throw e; + } finally { + FileBackend.close(os); + FileBackend.close(is); } - os.flush(); - os.close(); - is.close(); } private void updateImageBounds() { diff --git a/src/main/res/values/strings.xml b/src/main/res/values/strings.xml index 50c0ecf85..aa5bbec56 100644 --- a/src/main/res/values/strings.xml +++ b/src/main/res/values/strings.xml @@ -494,11 +494,13 @@ None Most recently used Choose quick action - File not found on remote server Search for contacts or groups Send private message %s has left the conference! Username Username This is not a valid username + Download failed: Server not found + Download failed: File not found + Download failed: Could not connect to host -- cgit v1.2.3 From d30515a85acaedb57d0d4308aeb72d96074f729a Mon Sep 17 00:00:00 2001 From: Daniel Gultsch Date: Mon, 10 Aug 2015 12:55:37 +0200 Subject: report wrong file size in otr encrypted jingle file transfers to be compatible with conversations > 1.6 --- src/main/java/eu/siacs/conversations/Config.java | 2 ++ .../siacs/conversations/services/AbstractConnectionManager.java | 3 ++- .../java/eu/siacs/conversations/xmpp/jingle/JingleConnection.java | 8 ++++++-- 3 files changed, 10 insertions(+), 3 deletions(-) (limited to 'src/main') diff --git a/src/main/java/eu/siacs/conversations/Config.java b/src/main/java/eu/siacs/conversations/Config.java index d1cb3cc11..f3cbffe68 100644 --- a/src/main/java/eu/siacs/conversations/Config.java +++ b/src/main/java/eu/siacs/conversations/Config.java @@ -42,6 +42,8 @@ public final class Config { public static final boolean ENCRYPT_ON_HTTP_UPLOADED = false; + public static final boolean REPORT_WRONG_FILESIZE_IN_OTR_JINGLE = true; + public static final boolean SHOW_REGENERATE_AXOLOTL_KEYS_BUTTON = false; public static final long MILLISECONDS_IN_DAY = 24 * 60 * 60 * 1000; diff --git a/src/main/java/eu/siacs/conversations/services/AbstractConnectionManager.java b/src/main/java/eu/siacs/conversations/services/AbstractConnectionManager.java index b7e7c8d3a..dbd7f3761 100644 --- a/src/main/java/eu/siacs/conversations/services/AbstractConnectionManager.java +++ b/src/main/java/eu/siacs/conversations/services/AbstractConnectionManager.java @@ -72,7 +72,8 @@ public class AbstractConnectionManager { Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding"); cipher.init(Cipher.ENCRYPT_MODE, new SecretKeySpec(file.getKey(), "AES"), ips); Log.d(Config.LOGTAG, "opening encrypted input stream"); - return new Pair(new CipherInputStream(is, cipher),(size / 16 + 1) * 16); + final int s = Config.REPORT_WRONG_FILESIZE_IN_OTR_JINGLE ? size : (size / 16 + 1) * 16; + return new Pair(new CipherInputStream(is, cipher),s); } } catch (InvalidKeyException e) { return null; diff --git a/src/main/java/eu/siacs/conversations/xmpp/jingle/JingleConnection.java b/src/main/java/eu/siacs/conversations/xmpp/jingle/JingleConnection.java index 29aafccef..d074bf9c0 100644 --- a/src/main/java/eu/siacs/conversations/xmpp/jingle/JingleConnection.java +++ b/src/main/java/eu/siacs/conversations/xmpp/jingle/JingleConnection.java @@ -272,7 +272,7 @@ public class JingleConnection implements Transferable { }); mergeCandidate(candidate); } else { - Log.d(Config.LOGTAG,"no primary candidate of our own was found"); + Log.d(Config.LOGTAG, "no primary candidate of our own was found"); sendInitRequest(); } } @@ -391,7 +391,11 @@ public class JingleConnection implements Transferable { } } this.mFileOutputStream = AbstractConnectionManager.createOutputStream(this.file,message.getEncryption() == Message.ENCRYPTION_AXOLOTL); - this.file.setExpectedSize(size); + if (message.getEncryption() == Message.ENCRYPTION_OTR && Config.REPORT_WRONG_FILESIZE_IN_OTR_JINGLE) { + this.file.setExpectedSize((size / 16 + 1) * 16); + } else { + this.file.setExpectedSize(size); + } Log.d(Config.LOGTAG, "receiving file: expecting size of " + this.file.getExpectedSize()); } else { this.sendCancel(); -- cgit v1.2.3 From fd81491b059983eb9bcafc91eb91055174bce131 Mon Sep 17 00:00:00 2001 From: Daniel Gultsch Date: Mon, 10 Aug 2015 19:48:36 +0200 Subject: put wake locks on out of band file transfers --- .../conversations/http/HttpDownloadConnection.java | 4 +++ .../conversations/http/HttpUploadConnection.java | 4 +++ .../services/AbstractConnectionManager.java | 7 ++++ .../xmpp/jingle/JingleConnection.java | 5 ++- .../xmpp/jingle/JingleSocks5Transport.java | 37 ++++++++-------------- 5 files changed, 32 insertions(+), 25 deletions(-) (limited to 'src/main') diff --git a/src/main/java/eu/siacs/conversations/http/HttpDownloadConnection.java b/src/main/java/eu/siacs/conversations/http/HttpDownloadConnection.java index 0c1ea5034..0d202bb92 100644 --- a/src/main/java/eu/siacs/conversations/http/HttpDownloadConnection.java +++ b/src/main/java/eu/siacs/conversations/http/HttpDownloadConnection.java @@ -2,6 +2,7 @@ package eu.siacs.conversations.http; import android.content.Intent; import android.net.Uri; +import android.os.PowerManager; import android.util.Log; import java.io.BufferedInputStream; @@ -228,7 +229,9 @@ public class HttpDownloadConnection implements Transferable { private void download() throws IOException { InputStream is = null; + PowerManager.WakeLock wakeLock = mHttpConnectionManager.createWakeLock("http_download_"+message.getUuid()); try { + wakeLock.acquire(); HttpURLConnection connection = (HttpURLConnection) mUrl.openConnection(); if (connection instanceof HttpsURLConnection) { mHttpConnectionManager.setupTrustManager((HttpsURLConnection) connection, interactive); @@ -253,6 +256,7 @@ public class HttpDownloadConnection implements Transferable { } finally { FileBackend.close(os); FileBackend.close(is); + wakeLock.release(); } } diff --git a/src/main/java/eu/siacs/conversations/http/HttpUploadConnection.java b/src/main/java/eu/siacs/conversations/http/HttpUploadConnection.java index 768915a94..69e9212ef 100644 --- a/src/main/java/eu/siacs/conversations/http/HttpUploadConnection.java +++ b/src/main/java/eu/siacs/conversations/http/HttpUploadConnection.java @@ -3,6 +3,7 @@ package eu.siacs.conversations.http; import android.app.PendingIntent; import android.content.Intent; import android.net.Uri; +import android.os.PowerManager; import android.util.Log; import android.util.Pair; @@ -143,7 +144,9 @@ public class HttpUploadConnection implements Transferable { private void upload() { OutputStream os = null; HttpURLConnection connection = null; + PowerManager.WakeLock wakeLock = mHttpConnectionManager.createWakeLock("http_upload_"+message.getUuid()); try { + wakeLock.acquire(); Log.d(Config.LOGTAG, "uploading to " + mPutUrl.toString()); connection = (HttpURLConnection) mPutUrl.openConnection(); if (connection instanceof HttpsURLConnection) { @@ -211,6 +214,7 @@ public class HttpUploadConnection implements Transferable { if (connection != null) { connection.disconnect(); } + wakeLock.release(); } } } diff --git a/src/main/java/eu/siacs/conversations/services/AbstractConnectionManager.java b/src/main/java/eu/siacs/conversations/services/AbstractConnectionManager.java index dbd7f3761..1b49e365a 100644 --- a/src/main/java/eu/siacs/conversations/services/AbstractConnectionManager.java +++ b/src/main/java/eu/siacs/conversations/services/AbstractConnectionManager.java @@ -1,5 +1,7 @@ package eu.siacs.conversations.services; +import android.content.Context; +import android.os.PowerManager; import android.util.Log; import android.util.Pair; @@ -118,4 +120,9 @@ public class AbstractConnectionManager { return null; } } + + public PowerManager.WakeLock createWakeLock(String name) { + PowerManager powerManager = (PowerManager) mXmppConnectionService.getSystemService(Context.POWER_SERVICE); + return powerManager.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK,name); + } } diff --git a/src/main/java/eu/siacs/conversations/xmpp/jingle/JingleConnection.java b/src/main/java/eu/siacs/conversations/xmpp/jingle/JingleConnection.java index d074bf9c0..be1caa568 100644 --- a/src/main/java/eu/siacs/conversations/xmpp/jingle/JingleConnection.java +++ b/src/main/java/eu/siacs/conversations/xmpp/jingle/JingleConnection.java @@ -28,7 +28,6 @@ import eu.siacs.conversations.entities.TransferablePlaceholder; import eu.siacs.conversations.persistance.FileBackend; import eu.siacs.conversations.services.AbstractConnectionManager; import eu.siacs.conversations.services.XmppConnectionService; -import eu.siacs.conversations.utils.Xmlns; import eu.siacs.conversations.xml.Element; import eu.siacs.conversations.xmpp.OnIqPacketReceived; import eu.siacs.conversations.xmpp.jid.Jid; @@ -1014,4 +1013,8 @@ public class JingleConnection implements Transferable { public int getProgress() { return this.mProgress; } + + public AbstractConnectionManager getConnectionManager() { + return this.mJingleConnectionManager; + } } diff --git a/src/main/java/eu/siacs/conversations/xmpp/jingle/JingleSocks5Transport.java b/src/main/java/eu/siacs/conversations/xmpp/jingle/JingleSocks5Transport.java index 7545dd646..556395aef 100644 --- a/src/main/java/eu/siacs/conversations/xmpp/jingle/JingleSocks5Transport.java +++ b/src/main/java/eu/siacs/conversations/xmpp/jingle/JingleSocks5Transport.java @@ -1,5 +1,6 @@ package eu.siacs.conversations.xmpp.jingle; +import android.os.PowerManager; import android.util.Log; import java.io.FileNotFoundException; @@ -96,14 +97,15 @@ public class JingleSocks5Transport extends JingleTransport { } - public void send(final DownloadableFile file, - final OnFileTransmissionStatusChanged callback) { + public void send(final DownloadableFile file, final OnFileTransmissionStatusChanged callback) { new Thread(new Runnable() { @Override public void run() { InputStream fileInputStream = null; + final PowerManager.WakeLock wakeLock = connection.getConnectionManager().createWakeLock("jingle_send_"+connection.getSessionId()); try { + wakeLock.acquire(); MessageDigest digest = MessageDigest.getInstance("SHA-1"); digest.reset(); fileInputStream = connection.getFileInputStream(); @@ -138,6 +140,7 @@ public class JingleSocks5Transport extends JingleTransport { callback.onFileTransferAborted(); } finally { FileBackend.close(fileInputStream); + wakeLock.release(); } } }).start(); @@ -150,7 +153,9 @@ public class JingleSocks5Transport extends JingleTransport { @Override public void run() { OutputStream fileOutputStream = null; + final PowerManager.WakeLock wakeLock = connection.getConnectionManager().createWakeLock("jingle_receive_"+connection.getSessionId()); try { + wakeLock.acquire(); MessageDigest digest = MessageDigest.getInstance("SHA-1"); digest.reset(); inputStream.skip(45); @@ -166,7 +171,7 @@ public class JingleSocks5Transport extends JingleTransport { double size = file.getExpectedSize(); long remainingSize = file.getExpectedSize(); byte[] buffer = new byte[8192]; - int count = buffer.length; + int count; while (remainingSize > 0) { count = inputStream.read(buffer); if (count == -1) { @@ -194,7 +199,9 @@ public class JingleSocks5Transport extends JingleTransport { Log.d(Config.LOGTAG, connection.getAccount().getJid().toBareJid() + ": "+e.getMessage()); callback.onFileTransferAborted(); } finally { + wakeLock.release(); FileBackend.close(fileOutputStream); + FileBackend.close(inputStream); } } }).start(); @@ -209,27 +216,9 @@ public class JingleSocks5Transport extends JingleTransport { } public void disconnect() { - if (this.outputStream != null) { - try { - this.outputStream.close(); - } catch (IOException e) { - - } - } - if (this.inputStream != null) { - try { - this.inputStream.close(); - } catch (IOException e) { - - } - } - if (this.socket != null) { - try { - this.socket.close(); - } catch (IOException e) { - - } - } + FileBackend.close(inputStream); + FileBackend.close(outputStream); + FileBackend.close(socket); } public boolean isEstablished() { -- cgit v1.2.3 From c0dcf4a55a50cb4c10699cb3bbf1b6765ce00633 Mon Sep 17 00:00:00 2001 From: Daniel Gultsch Date: Tue, 11 Aug 2015 15:13:17 +0200 Subject: changed color of 'whispered' prefix fixes #1326 --- src/main/java/eu/siacs/conversations/ui/adapter/MessageAdapter.java | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'src/main') diff --git a/src/main/java/eu/siacs/conversations/ui/adapter/MessageAdapter.java b/src/main/java/eu/siacs/conversations/ui/adapter/MessageAdapter.java index aec11b762..d95f6b449 100644 --- a/src/main/java/eu/siacs/conversations/ui/adapter/MessageAdapter.java +++ b/src/main/java/eu/siacs/conversations/ui/adapter/MessageAdapter.java @@ -303,8 +303,7 @@ public class MessageAdapter extends ArrayAdapter { } final Spannable span = new SpannableString(privateMarker + " " + formattedBody); - span.setSpan(new ForegroundColorSpan(activity - .getSecondaryTextColor()), 0, privateMarker + span.setSpan(new ForegroundColorSpan(getMessageTextColor(type,false)), 0, privateMarker .length(), Spannable.SPAN_EXCLUSIVE_EXCLUSIVE); span.setSpan(new StyleSpan(Typeface.BOLD), 0, privateMarker.length(), -- cgit v1.2.3 From 3677c6ec985f4b10d4d0c6a75c88973b2917ad4e Mon Sep 17 00:00:00 2001 From: Daniel Gultsch Date: Tue, 11 Aug 2015 15:23:52 +0200 Subject: use same code that is used to open files for images fixes #1323 --- src/main/java/eu/siacs/conversations/ui/adapter/MessageAdapter.java | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) (limited to 'src/main') diff --git a/src/main/java/eu/siacs/conversations/ui/adapter/MessageAdapter.java b/src/main/java/eu/siacs/conversations/ui/adapter/MessageAdapter.java index d95f6b449..1ddd6c44a 100644 --- a/src/main/java/eu/siacs/conversations/ui/adapter/MessageAdapter.java +++ b/src/main/java/eu/siacs/conversations/ui/adapter/MessageAdapter.java @@ -395,10 +395,7 @@ public class MessageAdapter extends ArrayAdapter { @Override public void onClick(View v) { - Intent intent = new Intent(Intent.ACTION_VIEW); - intent.setDataAndType(activity.xmppConnectionService - .getFileBackend().getJingleFileUri(message), "image/*"); - getContext().startActivity(intent); + openDownloadable(message); } }); viewHolder.image.setOnLongClickListener(openContextMenu); -- cgit v1.2.3 From dad90762b44878a436479a3998fec45111c9af46 Mon Sep 17 00:00:00 2001 From: Daniel Gultsch Date: Tue, 11 Aug 2015 16:50:00 +0200 Subject: do not touch pictures that are already in the right format fixed #522 --- .../conversations/http/HttpUploadConnection.java | 9 +- .../conversations/persistance/FileBackend.java | 37 +++--- .../services/AbstractConnectionManager.java | 14 +- .../services/XmppConnectionService.java | 21 ++- .../eu/siacs/conversations/utils/FileUtils.java | 144 +++++++++++++++++++++ .../xmpp/jingle/JingleConnection.java | 44 ++++--- 6 files changed, 218 insertions(+), 51 deletions(-) create mode 100644 src/main/java/eu/siacs/conversations/utils/FileUtils.java (limited to 'src/main') diff --git a/src/main/java/eu/siacs/conversations/http/HttpUploadConnection.java b/src/main/java/eu/siacs/conversations/http/HttpUploadConnection.java index 69e9212ef..2e5458423 100644 --- a/src/main/java/eu/siacs/conversations/http/HttpUploadConnection.java +++ b/src/main/java/eu/siacs/conversations/http/HttpUploadConnection.java @@ -7,6 +7,7 @@ import android.os.PowerManager; import android.util.Log; import android.util.Pair; +import java.io.FileNotFoundException; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; @@ -104,7 +105,13 @@ public class HttpUploadConnection implements Transferable { mXmppConnectionService.getRNG().nextBytes(this.key); this.file.setKeyAndIv(this.key); } - Pair pair = AbstractConnectionManager.createInputStream(file,true); + Pair pair; + try { + pair = AbstractConnectionManager.createInputStream(file, true); + } catch (FileNotFoundException e) { + fail(); + return; + } this.file.setExpectedSize(pair.second); this.mFileInputStream = pair.first; Jid host = account.getXmppConnection().findDiscoItemByFeature(Xmlns.HTTP_UPLOAD); diff --git a/src/main/java/eu/siacs/conversations/persistance/FileBackend.java b/src/main/java/eu/siacs/conversations/persistance/FileBackend.java index 13bbb2769..931158e5d 100644 --- a/src/main/java/eu/siacs/conversations/persistance/FileBackend.java +++ b/src/main/java/eu/siacs/conversations/persistance/FileBackend.java @@ -39,6 +39,7 @@ import eu.siacs.conversations.entities.Transferable; import eu.siacs.conversations.services.XmppConnectionService; import eu.siacs.conversations.utils.CryptoHelper; import eu.siacs.conversations.utils.ExifHelper; +import eu.siacs.conversations.utils.FileUtils; import eu.siacs.conversations.xmpp.pep.Avatar; public class FileBackend { @@ -126,25 +127,25 @@ public class FileBackend { return Bitmap.createBitmap(bitmap, 0, 0, w, h, mtx, true); } - public String getOriginalPath(Uri uri) { - String path = null; - if (uri.getScheme().equals("file")) { - return uri.getPath(); - } else if (uri.toString().startsWith("content://media/")) { - String[] projection = {MediaStore.MediaColumns.DATA}; - Cursor metaCursor = mXmppConnectionService.getContentResolver().query(uri, - projection, null, null, null); - if (metaCursor != null) { - try { - if (metaCursor.moveToFirst()) { - path = metaCursor.getString(0); - } - } finally { - metaCursor.close(); - } - } + public boolean useImageAsIs(Uri uri) { + String path = getOriginalPath(uri); + if (path == null) { + return false; } - return path; + Log.d(Config.LOGTAG,"using image as is. path: "+path); + BitmapFactory.Options options = new BitmapFactory.Options(); + options.inJustDecodeBounds = true; + try { + BitmapFactory.decodeStream(mXmppConnectionService.getContentResolver().openInputStream(uri), null, options); + return (options.outWidth <= Config.IMAGE_SIZE && options.outHeight <= Config.IMAGE_SIZE && options.outMimeType.contains(Config.IMAGE_FORMAT.name().toLowerCase())); + } catch (FileNotFoundException e) { + return false; + } + } + + public String getOriginalPath(Uri uri) { + Log.d(Config.LOGTAG,"get original path for uri: "+uri.toString()); + return FileUtils.getPath(mXmppConnectionService,uri); } public DownloadableFile copyFileToPrivateStorage(Message message, Uri uri) throws FileCopyException { diff --git a/src/main/java/eu/siacs/conversations/services/AbstractConnectionManager.java b/src/main/java/eu/siacs/conversations/services/AbstractConnectionManager.java index 1b49e365a..5def05dd4 100644 --- a/src/main/java/eu/siacs/conversations/services/AbstractConnectionManager.java +++ b/src/main/java/eu/siacs/conversations/services/AbstractConnectionManager.java @@ -51,17 +51,13 @@ public class AbstractConnectionManager { } } - public static Pair createInputStream(DownloadableFile file, boolean gcm) { + public static Pair createInputStream(DownloadableFile file, boolean gcm) throws FileNotFoundException { FileInputStream is; int size; - try { - is = new FileInputStream(file); - size = (int) file.getSize(); - if (file.getKey() == null) { - return new Pair(is,size); - } - } catch (FileNotFoundException e) { - return null; + is = new FileInputStream(file); + size = (int) file.getSize(); + if (file.getKey() == null) { + return new Pair(is,size); } try { if (gcm) { diff --git a/src/main/java/eu/siacs/conversations/services/XmppConnectionService.java b/src/main/java/eu/siacs/conversations/services/XmppConnectionService.java index ffe587d69..ed3bb8792 100644 --- a/src/main/java/eu/siacs/conversations/services/XmppConnectionService.java +++ b/src/main/java/eu/siacs/conversations/services/XmppConnectionService.java @@ -404,8 +404,12 @@ public class XmppConnectionService extends Service implements OnPhoneContactsLoa } } - public void attachImageToConversation(final Conversation conversation, - final Uri uri, final UiCallback callback) { + public void attachImageToConversation(final Conversation conversation, final Uri uri, final UiCallback callback) { + if (getFileBackend().useImageAsIs(uri)) { + Log.d(Config.LOGTAG,"using image as is"); + attachFileToConversation(conversation, uri, callback); + return; + } final Message message; if (conversation.getNextEncryption() == Message.ENCRYPTION_PGP) { message = new Message(conversation, "", Message.ENCRYPTION_DECRYPTED); @@ -855,7 +859,7 @@ public class XmppConnectionService extends Service implements OnPhoneContactsLoa } else { Log.d(Config.LOGTAG, account.getJid().toBareJid() + ": fetching roster"); } - iqPacket.query(Xmlns.ROSTER).setAttribute("ver",account.getRosterVersion()); + iqPacket.query(Xmlns.ROSTER).setAttribute("ver", account.getRosterVersion()); sendIqPacket(account,iqPacket,mIqParser); } @@ -1000,6 +1004,10 @@ public class XmppConnectionService extends Service implements OnPhoneContactsLoa public void onMessageFound(Message message) { if (!getFileBackend().isFileAvailable(message)) { message.setTransferable(new TransferablePlaceholder(Transferable.STATUS_DELETED)); + final int s = message.getStatus(); + if(s == Message.STATUS_WAITING || s == Message.STATUS_OFFERED || s == Message.STATUS_UNSEND) { + markMessage(message,Message.STATUS_SEND_FAILED); + } } } }); @@ -1011,7 +1019,12 @@ public class XmppConnectionService extends Service implements OnPhoneContactsLoa if (message != null) { if (!getFileBackend().isFileAvailable(message)) { message.setTransferable(new TransferablePlaceholder(Transferable.STATUS_DELETED)); - updateConversationUi(); + final int s = message.getStatus(); + if(s == Message.STATUS_WAITING || s == Message.STATUS_OFFERED || s == Message.STATUS_UNSEND) { + markMessage(message,Message.STATUS_SEND_FAILED); + } else { + updateConversationUi(); + } } return; } diff --git a/src/main/java/eu/siacs/conversations/utils/FileUtils.java b/src/main/java/eu/siacs/conversations/utils/FileUtils.java new file mode 100644 index 000000000..a13300d43 --- /dev/null +++ b/src/main/java/eu/siacs/conversations/utils/FileUtils.java @@ -0,0 +1,144 @@ +package eu.siacs.conversations.utils; + +import android.annotation.SuppressLint; +import android.content.ContentUris; +import android.content.Context; +import android.database.Cursor; +import android.net.Uri; +import android.os.Build; +import android.os.Environment; +import android.provider.DocumentsContract; +import android.provider.MediaStore; + +public class FileUtils { + + /** + * Get a file path from a Uri. This will get the the path for Storage Access + * Framework Documents, as well as the _data field for the MediaStore and + * other file-based ContentProviders. + * + * @param context The context. + * @param uri The Uri to query. + * @author paulburke + */ + @SuppressLint("NewApi") + public static String getPath(final Context context, final Uri uri) { + + final boolean isKitKat = Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT; + + // DocumentProvider + if (isKitKat && DocumentsContract.isDocumentUri(context, uri)) { + // ExternalStorageProvider + if (isExternalStorageDocument(uri)) { + final String docId = DocumentsContract.getDocumentId(uri); + final String[] split = docId.split(":"); + final String type = split[0]; + + if ("primary".equalsIgnoreCase(type)) { + return Environment.getExternalStorageDirectory() + "/" + split[1]; + } + + // TODO handle non-primary volumes + } + // DownloadsProvider + else if (isDownloadsDocument(uri)) { + + final String id = DocumentsContract.getDocumentId(uri); + final Uri contentUri = ContentUris.withAppendedId( + Uri.parse("content://downloads/public_downloads"), Long.valueOf(id)); + + return getDataColumn(context, contentUri, null, null); + } + // MediaProvider + else if (isMediaDocument(uri)) { + final String docId = DocumentsContract.getDocumentId(uri); + final String[] split = docId.split(":"); + final String type = split[0]; + + Uri contentUri = null; + if ("image".equals(type)) { + contentUri = MediaStore.Images.Media.EXTERNAL_CONTENT_URI; + } else if ("video".equals(type)) { + contentUri = MediaStore.Video.Media.EXTERNAL_CONTENT_URI; + } else if ("audio".equals(type)) { + contentUri = MediaStore.Audio.Media.EXTERNAL_CONTENT_URI; + } + + final String selection = "_id=?"; + final String[] selectionArgs = new String[]{ + split[1] + }; + + return getDataColumn(context, contentUri, selection, selectionArgs); + } + } + // MediaStore (and general) + else if ("content".equalsIgnoreCase(uri.getScheme())) { + return getDataColumn(context, uri, null, null); + } + // File + else if ("file".equalsIgnoreCase(uri.getScheme())) { + return uri.getPath(); + } + + return null; + } + + /** + * Get the value of the data column for this Uri. This is useful for + * MediaStore Uris, and other file-based ContentProviders. + * + * @param context The context. + * @param uri The Uri to query. + * @param selection (Optional) Filter used in the query. + * @param selectionArgs (Optional) Selection arguments used in the query. + * @return The value of the _data column, which is typically a file path. + */ + public static String getDataColumn(Context context, Uri uri, String selection, + String[] selectionArgs) { + + Cursor cursor = null; + final String column = "_data"; + final String[] projection = { + column + }; + + try { + cursor = context.getContentResolver().query(uri, projection, selection, selectionArgs, + null); + if (cursor != null && cursor.moveToFirst()) { + final int column_index = cursor.getColumnIndexOrThrow(column); + return cursor.getString(column_index); + } + } finally { + if (cursor != null) + cursor.close(); + } + return null; + } + + + /** + * @param uri The Uri to check. + * @return Whether the Uri authority is ExternalStorageProvider. + */ + public static boolean isExternalStorageDocument(Uri uri) { + return "com.android.externalstorage.documents".equals(uri.getAuthority()); + } + + /** + * @param uri The Uri to check. + * @return Whether the Uri authority is DownloadsProvider. + */ + public static boolean isDownloadsDocument(Uri uri) { + return "com.android.providers.downloads.documents".equals(uri.getAuthority()); + } + + /** + * @param uri The Uri to check. + * @return Whether the Uri authority is MediaProvider. + */ + public static boolean isMediaDocument(Uri uri) { + return "com.android.providers.media.documents".equals(uri.getAuthority()); + } +} diff --git a/src/main/java/eu/siacs/conversations/xmpp/jingle/JingleConnection.java b/src/main/java/eu/siacs/conversations/xmpp/jingle/JingleConnection.java index be1caa568..7b140842a 100644 --- a/src/main/java/eu/siacs/conversations/xmpp/jingle/JingleConnection.java +++ b/src/main/java/eu/siacs/conversations/xmpp/jingle/JingleConnection.java @@ -5,6 +5,7 @@ import android.net.Uri; import android.util.Log; import android.util.Pair; +import java.io.FileNotFoundException; import java.io.InputStream; import java.io.OutputStream; import java.util.ArrayList; @@ -413,26 +414,31 @@ public class JingleConnection implements Transferable { content.setTransportId(this.transportId); this.file = this.mXmppConnectionService.getFileBackend().getFile(message, false); Pair pair; - if (message.getEncryption() == Message.ENCRYPTION_OTR) { - Conversation conversation = this.message.getConversation(); - if (!this.mXmppConnectionService.renewSymmetricKey(conversation)) { - Log.d(Config.LOGTAG,account.getJid().toBareJid()+": could not set symmetric key"); - cancel(); + try { + if (message.getEncryption() == Message.ENCRYPTION_OTR) { + Conversation conversation = this.message.getConversation(); + if (!this.mXmppConnectionService.renewSymmetricKey(conversation)) { + Log.d(Config.LOGTAG, account.getJid().toBareJid() + ": could not set symmetric key"); + cancel(); + } + this.file.setKeyAndIv(conversation.getSymmetricKey()); + pair = AbstractConnectionManager.createInputStream(this.file, false); + this.file.setExpectedSize(pair.second); + content.setFileOffer(this.file, true); + } else if (message.getEncryption() == Message.ENCRYPTION_AXOLOTL) { + this.file.setKey(mXmppAxolotlMessage.getInnerKey()); + this.file.setIv(mXmppAxolotlMessage.getIV()); + pair = AbstractConnectionManager.createInputStream(this.file, true); + this.file.setExpectedSize(pair.second); + content.setFileOffer(this.file, false).addChild(mXmppAxolotlMessage.toElement()); + } else { + pair = AbstractConnectionManager.createInputStream(this.file, false); + this.file.setExpectedSize(pair.second); + content.setFileOffer(this.file, false); } - this.file.setKeyAndIv(conversation.getSymmetricKey()); - pair = AbstractConnectionManager.createInputStream(this.file,false); - this.file.setExpectedSize(pair.second); - content.setFileOffer(this.file, true); - } else if (message.getEncryption() == Message.ENCRYPTION_AXOLOTL) { - this.file.setKey(mXmppAxolotlMessage.getInnerKey()); - this.file.setIv(mXmppAxolotlMessage.getIV()); - pair = AbstractConnectionManager.createInputStream(this.file,true); - this.file.setExpectedSize(pair.second); - content.setFileOffer(this.file, false).addChild(mXmppAxolotlMessage.toElement()); - } else { - pair = AbstractConnectionManager.createInputStream(this.file,false); - this.file.setExpectedSize(pair.second); - content.setFileOffer(this.file, false); + } catch (FileNotFoundException e) { + cancel(); + return; } this.mFileInputStream = pair.first; this.transportId = this.mJingleConnectionManager.nextRandomId(); -- cgit v1.2.3