From f5019ba96647bd1c33153e6e9099d21dcf47bfa7 Mon Sep 17 00:00:00 2001 From: iNPUTmice Date: Wed, 15 Oct 2014 22:08:13 +0200 Subject: [PATCH] detect deleted files on start up. got rid of lagecy image provider for performance reasons. NOTE: this will prevent you to access images older than version 0.6 --- AndroidManifest.xml | 7 +- res/values/strings.xml | 1 + .../siacs/conversations/crypto/PgpEngine.java | 8 +- .../conversations/entities/Downloadable.java | 1 + .../conversations/http/HttpConnection.java | 23 ++-- .../http/HttpConnectionManager.java | 8 +- .../persistance/FileBackend.java | 51 ++------ .../conversations/services/ImageProvider.java | 109 ------------------ .../services/XmppConnectionService.java | 32 ++++- .../ui/adapter/ConversationAdapter.java | 2 + .../ui/adapter/MessageAdapter.java | 18 +-- .../xmpp/jingle/JingleConnection.java | 4 +- 12 files changed, 67 insertions(+), 197 deletions(-) delete mode 100644 src/eu/siacs/conversations/services/ImageProvider.java diff --git a/AndroidManifest.xml b/AndroidManifest.xml index ce4ea5df..3263cdd6 100644 --- a/AndroidManifest.xml +++ b/AndroidManifest.xml @@ -25,11 +25,6 @@ android:theme="@style/ConversationsTheme" > - - @@ -124,4 +119,4 @@ - + \ No newline at end of file diff --git a/res/values/strings.xml b/res/values/strings.xml index 22622f60..18eec00a 100644 --- a/res/values/strings.xml +++ b/res/values/strings.xml @@ -267,5 +267,6 @@ You have been kicked from this conference using account %s Checking image on HTTP host + The image file has been deleted diff --git a/src/eu/siacs/conversations/crypto/PgpEngine.java b/src/eu/siacs/conversations/crypto/PgpEngine.java index e5524df5..2696c7d2 100644 --- a/src/eu/siacs/conversations/crypto/PgpEngine.java +++ b/src/eu/siacs/conversations/crypto/PgpEngine.java @@ -88,9 +88,9 @@ public class PgpEngine { } else if (message.getType() == Message.TYPE_IMAGE) { try { final DownloadableFile inputFile = this.mXmppConnectionService - .getFileBackend().getConversationsFile(message, false); + .getFileBackend().getFile(message, false); final DownloadableFile outputFile = this.mXmppConnectionService - .getFileBackend().getConversationsFile(message, true); + .getFileBackend().getFile(message, true); outputFile.createNewFile(); InputStream is = new FileInputStream(inputFile); OutputStream os = new FileOutputStream(outputFile); @@ -198,9 +198,9 @@ public class PgpEngine { } else if (message.getType() == Message.TYPE_IMAGE) { try { DownloadableFile inputFile = this.mXmppConnectionService - .getFileBackend().getConversationsFile(message, true); + .getFileBackend().getFile(message, true); DownloadableFile outputFile = this.mXmppConnectionService - .getFileBackend().getConversationsFile(message, false); + .getFileBackend().getFile(message, false); outputFile.createNewFile(); InputStream is = new FileInputStream(inputFile); OutputStream os = new FileOutputStream(outputFile); diff --git a/src/eu/siacs/conversations/entities/Downloadable.java b/src/eu/siacs/conversations/entities/Downloadable.java index 3fc94c58..c8ca599f 100644 --- a/src/eu/siacs/conversations/entities/Downloadable.java +++ b/src/eu/siacs/conversations/entities/Downloadable.java @@ -10,6 +10,7 @@ public interface Downloadable { public static final int STATUS_FAILED = 0x202; public static final int STATUS_OFFER = 0x203; public static final int STATUS_DOWNLOADING = 0x204; + public static final int STATUS_DELETED = 0x205; public void start(); diff --git a/src/eu/siacs/conversations/http/HttpConnection.java b/src/eu/siacs/conversations/http/HttpConnection.java index c53b9fd5..34036412 100644 --- a/src/eu/siacs/conversations/http/HttpConnection.java +++ b/src/eu/siacs/conversations/http/HttpConnection.java @@ -9,7 +9,9 @@ import java.net.URL; import javax.net.ssl.HttpsURLConnection; +import android.content.Intent; import android.graphics.BitmapFactory; +import android.net.Uri; import eu.siacs.conversations.entities.Downloadable; import eu.siacs.conversations.entities.DownloadableFile; @@ -24,8 +26,8 @@ public class HttpConnection implements Downloadable { private URL mUrl; private Message message; private DownloadableFile file; - private long mPreviousFileSize = 0; private int mStatus = Downloadable.STATUS_UNKNOWN; + private boolean mAutostart = true; public HttpConnection(HttpConnectionManager manager) { this.mHttpConnectionManager = manager; @@ -44,23 +46,14 @@ public class HttpConnection implements Downloadable { try { mUrl = new URL(message.getBody()); this.file = mXmppConnectionService.getFileBackend() - .getConversationsFile(message, false); + .getFile(message, false); + this.mAutostart = true; checkFileSize(); } catch (MalformedURLException e) { this.cancel(); } } - public void init(Message message, URL url) { - this.message = message; - this.message.setDownloadable(this); - this.mUrl = url; - this.file = mXmppConnectionService.getFileBackend() - .getConversationsFile(message, false); - this.mPreviousFileSize = message.getImageParams().size; - checkFileSize(); - } - private void checkFileSize() { changeStatus(STATUS_CHECKING); new Thread(new FileSizeChecker()).start(); @@ -74,6 +67,9 @@ public class HttpConnection implements Downloadable { } private void finish() { + Intent intent = new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE); + intent.setData(Uri.fromFile(file)); + mXmppConnectionService.sendBroadcast(intent); message.setDownloadable(null); mHttpConnectionManager.finishConnection(this); } @@ -96,8 +92,7 @@ public class HttpConnection implements Downloadable { } file.setExpectedSize(size); message.setType(Message.TYPE_IMAGE); - if (size <= mHttpConnectionManager.getAutoAcceptFileSize() - || size == mPreviousFileSize) { + if (size <= mHttpConnectionManager.getAutoAcceptFileSize() && mAutostart) { start(); } else { changeStatus(STATUS_OFFER); diff --git a/src/eu/siacs/conversations/http/HttpConnectionManager.java b/src/eu/siacs/conversations/http/HttpConnectionManager.java index 011ecc3f..ff71d45c 100644 --- a/src/eu/siacs/conversations/http/HttpConnectionManager.java +++ b/src/eu/siacs/conversations/http/HttpConnectionManager.java @@ -5,6 +5,7 @@ import java.util.List; import java.util.concurrent.CopyOnWriteArrayList; import eu.siacs.conversations.entities.Message; +import eu.siacs.conversations.entities.Message.ImageParams; import eu.siacs.conversations.services.AbstractConnectionManager; import eu.siacs.conversations.services.XmppConnectionService; @@ -23,13 +24,6 @@ public class HttpConnectionManager extends AbstractConnectionManager { return connection; } - public HttpConnection createNewConnection(Message message, URL url) { - HttpConnection connection = new HttpConnection(this); - connection.init(message, url); - this.connections.add(connection); - return connection; - } - public void finishConnection(HttpConnection connection) { this.connections.remove(connection); } diff --git a/src/eu/siacs/conversations/persistance/FileBackend.java b/src/eu/siacs/conversations/persistance/FileBackend.java index 35aa9042..72c620a7 100644 --- a/src/eu/siacs/conversations/persistance/FileBackend.java +++ b/src/eu/siacs/conversations/persistance/FileBackend.java @@ -34,7 +34,6 @@ import eu.siacs.conversations.R; import eu.siacs.conversations.entities.Conversation; import eu.siacs.conversations.entities.DownloadableFile; import eu.siacs.conversations.entities.Message; -import eu.siacs.conversations.services.ImageProvider; import eu.siacs.conversations.utils.CryptoHelper; import eu.siacs.conversations.utils.UIHelper; import eu.siacs.conversations.xmpp.pep.Avatar; @@ -66,34 +65,11 @@ public class FileBackend { return thumbnailCache; } - public DownloadableFile getJingleFileLegacy(Message message) { - return getJingleFileLegacy(message, true); + public DownloadableFile getFile(Message message) { + return getFile(message, true); } - public DownloadableFile getJingleFileLegacy(Message message, - boolean decrypted) { - Conversation conversation = message.getConversation(); - String prefix = context.getFilesDir().getAbsolutePath(); - String path = prefix + "/" + conversation.getAccount().getJid() + "/" - + conversation.getContactJid(); - String filename; - if ((decrypted) || (message.getEncryption() == Message.ENCRYPTION_NONE)) { - filename = message.getUuid() + ".webp"; - } else { - if (message.getEncryption() == Message.ENCRYPTION_OTR) { - filename = message.getUuid() + ".webp"; - } else { - filename = message.getUuid() + ".webp.pgp"; - } - } - return new DownloadableFile(path + "/" + filename); - } - - public DownloadableFile getJingleFile(Message message) { - return getConversationsFile(message, true); - } - - public DownloadableFile getConversationsFile(Message message, + public DownloadableFile getFile(Message message, boolean decrypted) { StringBuilder filename = new StringBuilder(); filename.append(Environment.getExternalStoragePublicDirectory( @@ -151,7 +127,7 @@ public class FileBackend { try { InputStream is = context.getContentResolver() .openInputStream(image); - DownloadableFile file = getJingleFile(message); + DownloadableFile file = getFile(message); file.getParentFile().mkdirs(); file.createNewFile(); Bitmap originalBitmap; @@ -240,7 +216,7 @@ public class FileBackend { } public Bitmap getImageFromMessage(Message message) { - return BitmapFactory.decodeFile(getJingleFile(message) + return BitmapFactory.decodeFile(getFile(message) .getAbsolutePath()); } @@ -248,10 +224,7 @@ public class FileBackend { throws FileNotFoundException { Bitmap thumbnail = thumbnailCache.get(message.getUuid()); if ((thumbnail == null) && (!cacheOnly)) { - File file = getJingleFile(message); - if (!file.exists()) { - file = getJingleFileLegacy(message); - } + File file = getFile(message); BitmapFactory.Options options = new BitmapFactory.Options(); options.inSampleSize = calcSampleSize(file, size); Bitmap fullsize = BitmapFactory.decodeFile(file.getAbsolutePath(), @@ -447,12 +420,8 @@ public class FileBackend { } public Uri getJingleFileUri(Message message) { - File file = getJingleFile(message); - if (file.exists()) { - return Uri.parse("file://" + file.getAbsolutePath()); - } else { - return ImageProvider.getProviderUri(message); - } + File file = getFile(message); + return Uri.parse("file://" + file.getAbsolutePath()); } public class ImageCopyException extends Exception { @@ -476,4 +445,8 @@ public class FileBackend { } return cropCenterSquare(bm, UIHelper.getRealPx(size, context)); } + + public boolean isFileAvailable(Message message) { + return getFile(message).exists(); + } } diff --git a/src/eu/siacs/conversations/services/ImageProvider.java b/src/eu/siacs/conversations/services/ImageProvider.java deleted file mode 100644 index ac78a454..00000000 --- a/src/eu/siacs/conversations/services/ImageProvider.java +++ /dev/null @@ -1,109 +0,0 @@ -package eu.siacs.conversations.services; - -import java.io.File; -import java.io.FileNotFoundException; - -import eu.siacs.conversations.Config; -import eu.siacs.conversations.entities.Account; -import eu.siacs.conversations.entities.Conversation; -import eu.siacs.conversations.entities.Message; -import eu.siacs.conversations.persistance.DatabaseBackend; -import eu.siacs.conversations.persistance.FileBackend; -import android.content.ContentProvider; -import android.content.ContentValues; -import android.database.Cursor; -import android.net.Uri; -import android.os.ParcelFileDescriptor; -import android.util.Log; - -public class ImageProvider extends ContentProvider { - - @Override - public ParcelFileDescriptor openFile(Uri uri, String mode) - throws FileNotFoundException { - ParcelFileDescriptor pfd; - FileBackend fileBackend = new FileBackend(getContext()); - if ("r".equals(mode)) { - DatabaseBackend databaseBackend = DatabaseBackend - .getInstance(getContext()); - String uuids = uri.getPath(); - Log.d(Config.LOGTAG, "uuids = " + uuids + " mode=" + mode); - if (uuids == null) { - throw new FileNotFoundException(); - } - String[] uuidsSplited = uuids.split("/", 2); - if (uuidsSplited.length != 3) { - throw new FileNotFoundException(); - } - String conversationUuid = uuidsSplited[1]; - String messageUuid = uuidsSplited[2].split("\\.")[0]; - - Log.d(Config.LOGTAG, "messageUuid=" + messageUuid); - - Conversation conversation = databaseBackend - .findConversationByUuid(conversationUuid); - if (conversation == null) { - throw new FileNotFoundException("conversation " - + conversationUuid + " could not be found"); - } - Message message = databaseBackend.findMessageByUuid(messageUuid); - if (message == null) { - throw new FileNotFoundException("message " + messageUuid - + " could not be found"); - } - - Account account = databaseBackend.findAccountByUuid(conversation - .getAccountUuid()); - if (account == null) { - throw new FileNotFoundException("account " - + conversation.getAccountUuid() + " cound not be found"); - } - message.setConversation(conversation); - conversation.setAccount(account); - - File file = fileBackend.getJingleFileLegacy(message); - pfd = ParcelFileDescriptor.open(file, - ParcelFileDescriptor.MODE_READ_ONLY); - return pfd; - } else { - throw new FileNotFoundException(); - } - } - - @Override - public int delete(Uri arg0, String arg1, String[] arg2) { - return 0; - } - - @Override - public String getType(Uri arg0) { - return null; - } - - @Override - public Uri insert(Uri arg0, ContentValues arg1) { - return null; - } - - @Override - public boolean onCreate() { - return false; - } - - @Override - public Cursor query(Uri arg0, String[] arg1, String arg2, String[] arg3, - String arg4) { - return null; - } - - @Override - public int update(Uri arg0, ContentValues arg1, String arg2, String[] arg3) { - return 0; - } - - public static Uri getProviderUri(Message message) { - return Uri.parse("content://eu.siacs.conversations.images/" - + message.getConversationUuid() + "/" + message.getUuid() - + ".webp"); - } -} \ No newline at end of file diff --git a/src/eu/siacs/conversations/services/XmppConnectionService.java b/src/eu/siacs/conversations/services/XmppConnectionService.java index 07897f8c..04d5711a 100644 --- a/src/eu/siacs/conversations/services/XmppConnectionService.java +++ b/src/eu/siacs/conversations/services/XmppConnectionService.java @@ -27,6 +27,7 @@ import eu.siacs.conversations.entities.Account; import eu.siacs.conversations.entities.Bookmark; import eu.siacs.conversations.entities.Contact; import eu.siacs.conversations.entities.Conversation; +import eu.siacs.conversations.entities.Downloadable; import eu.siacs.conversations.entities.Message; import eu.siacs.conversations.entities.MucOptions; import eu.siacs.conversations.entities.MucOptions.OnRenameListener; @@ -797,11 +798,21 @@ public class XmppConnectionService extends Service { Account account = accountLookupTable.get(conv.getAccountUuid()); conv.setAccount(account); conv.setMessages(databaseBackend.getMessages(conv, 50)); + checkDeletedFiles(conv); } } - return this.conversations; } + + private void checkDeletedFiles(Conversation conversation) { + for(Message message : conversation.getMessages()) { + if (message.getType() == Message.TYPE_IMAGE && message.getEncryption() != Message.ENCRYPTION_PGP) { + if (!getFileBackend().isFileAvailable(message)) { + message.setDownloadable(new DeletedDownloadable()); + } + } + } + } public void populateWithOrderedConversations(List list) { populateWithOrderedConversations(list, true); @@ -1833,4 +1844,23 @@ public class XmppConnectionService extends Service { public HttpConnectionManager getHttpConnectionManager() { return this.mHttpConnectionManager; } + + private class DeletedDownloadable implements Downloadable { + + @Override + public void start() { + return; + } + + @Override + public int getStatus() { + return Downloadable.STATUS_DELETED; + } + + @Override + public long getFileSize() { + return 0; + } + + } } diff --git a/src/eu/siacs/conversations/ui/adapter/ConversationAdapter.java b/src/eu/siacs/conversations/ui/adapter/ConversationAdapter.java index 6943a85c..bd37f7fc 100644 --- a/src/eu/siacs/conversations/ui/adapter/ConversationAdapter.java +++ b/src/eu/siacs/conversations/ui/adapter/ConversationAdapter.java @@ -92,6 +92,8 @@ public class ConversationAdapter extends ArrayAdapter { mLastMessage.setText(R.string.receiving_image); } else if (d.getStatus() == Downloadable.STATUS_OFFER) { mLastMessage.setText(R.string.image_offered_for_download); + } else if (d.getStatus() == Downloadable.STATUS_DELETED) { + mLastMessage.setText(R.string.image_file_deleted); } else { mLastMessage.setText(""); } diff --git a/src/eu/siacs/conversations/ui/adapter/MessageAdapter.java b/src/eu/siacs/conversations/ui/adapter/MessageAdapter.java index efb07292..24a824b3 100644 --- a/src/eu/siacs/conversations/ui/adapter/MessageAdapter.java +++ b/src/eu/siacs/conversations/ui/adapter/MessageAdapter.java @@ -1,7 +1,5 @@ package eu.siacs.conversations.ui.adapter; -import java.net.MalformedURLException; -import java.net.URL; import java.util.HashMap; import java.util.List; @@ -476,6 +474,8 @@ public class MessageAdapter extends ArrayAdapter { } else if (d != null && d.getStatus() == Downloadable.STATUS_CHECKING) { displayInfoMessage(viewHolder, R.string.checking_image); + } else if (d != null && d.getStatus() == Downloadable.STATUS_DELETED) { + displayInfoMessage(viewHolder, R.string.image_file_deleted); } else if (d != null && d.getStatus() == Downloadable.STATUS_OFFER) { viewHolder.image.setVisibility(View.GONE); viewHolder.messageBody.setVisibility(View.GONE); @@ -531,19 +531,7 @@ public class MessageAdapter extends ArrayAdapter { downloadable.start(); return true; } else { - ImageParams params = message.getImageParams(); - if (params.origin != null) { - try { - URL url = new URL(params.origin); - activity.xmppConnectionService.getHttpConnectionManager() - .createNewConnection(message, url); - return true; - } catch (MalformedURLException e) { - return false; - } - } else { - return false; - } + return false; } } diff --git a/src/eu/siacs/conversations/xmpp/jingle/JingleConnection.java b/src/eu/siacs/conversations/xmpp/jingle/JingleConnection.java index 8e4714f4..bfc3c18c 100644 --- a/src/eu/siacs/conversations/xmpp/jingle/JingleConnection.java +++ b/src/eu/siacs/conversations/xmpp/jingle/JingleConnection.java @@ -327,7 +327,7 @@ public class JingleConnection implements Downloadable { .push(message); } this.file = this.mXmppConnectionService.getFileBackend() - .getConversationsFile(message, false); + .getFile(message, false); if (message.getEncryption() == Message.ENCRYPTION_OTR) { byte[] key = conversation.getSymmetricKey(); if (key == null) { @@ -359,7 +359,7 @@ public class JingleConnection implements Downloadable { if (message.getType() == Message.TYPE_IMAGE) { content.setTransportId(this.transportId); this.file = this.mXmppConnectionService.getFileBackend() - .getConversationsFile(message, false); + .getFile(message, false); if (message.getEncryption() == Message.ENCRYPTION_OTR) { Conversation conversation = this.message.getConversation(); this.mXmppConnectionService.renewSymmetricKey(conversation);