diff options
author | Daniel Gultsch <daniel@gultsch.de> | 2016-07-23 16:12:45 +0200 |
---|---|---|
committer | Christian Schneppe <christian@pix-art.de> | 2016-07-25 19:47:59 +0200 |
commit | 3fbee39579b4b2232fc98d50f6b16ec4f9f33022 (patch) | |
tree | 957eec5a50c28d221169d8b4e6e7e3f325102a37 /src/main/java/eu/siacs/conversations | |
parent | c474c17081ec036234c3c8a7c68e6432a05b2d4d (diff) |
refactored deleted file detection to monitor entire sd card. fixes #1968
Diffstat (limited to 'src/main/java/eu/siacs/conversations')
-rw-r--r-- | src/main/java/eu/siacs/conversations/services/XmppConnectionService.java | 42 | ||||
-rw-r--r-- | src/main/java/eu/siacs/conversations/utils/ConversationsFileObserver.java | 72 |
2 files changed, 95 insertions, 19 deletions
diff --git a/src/main/java/eu/siacs/conversations/services/XmppConnectionService.java b/src/main/java/eu/siacs/conversations/services/XmppConnectionService.java index c0437f539..c349d20cb 100644 --- a/src/main/java/eu/siacs/conversations/services/XmppConnectionService.java +++ b/src/main/java/eu/siacs/conversations/services/XmppConnectionService.java @@ -18,7 +18,7 @@ import android.net.Uri; import android.os.Binder; import android.os.Build; import android.os.Bundle; -import android.os.FileObserver; +import android.os.Environment; import android.os.IBinder; import android.os.PowerManager; import android.os.PowerManager.WakeLock; @@ -71,6 +71,7 @@ import eu.siacs.conversations.entities.Blockable; import eu.siacs.conversations.entities.Bookmark; import eu.siacs.conversations.entities.Contact; import eu.siacs.conversations.entities.Conversation; +import eu.siacs.conversations.entities.DownloadableFile; import eu.siacs.conversations.entities.Message; import eu.siacs.conversations.entities.MucOptions; import eu.siacs.conversations.entities.MucOptions.OnRenameListener; @@ -92,6 +93,7 @@ import eu.siacs.conversations.parser.PresenceParser; import eu.siacs.conversations.persistance.DatabaseBackend; import eu.siacs.conversations.persistance.FileBackend; import eu.siacs.conversations.ui.UiCallback; +import eu.siacs.conversations.utils.ConversationsFileObserver; import eu.siacs.conversations.utils.CryptoHelper; import eu.siacs.conversations.utils.ExceptionHelper; import eu.siacs.conversations.utils.OnPhoneContactsLoadedListener; @@ -212,14 +214,14 @@ public class XmppConnectionService extends Service { private MessageArchiveService mMessageArchiveService = new MessageArchiveService(this); private PushManagementService mPushManagementService = new PushManagementService(this); private OnConversationUpdate mOnConversationUpdate = null; - private final FileObserver fileObserver = new FileObserver( - FileBackend.getConversationsImageDirectory()) { + + private final ConversationsFileObserver fileObserver = new ConversationsFileObserver( + Environment.getExternalStorageDirectory().getAbsolutePath() + ) { @Override public void onEvent(int event, String path) { - if (event == FileObserver.DELETE) { - markFileDeleted(path.split("\\.")[0]); - } + markFileDeleted(path); } }; private final OnJinglePacketReceived jingleListener = new OnJinglePacketReceived() { @@ -765,7 +767,6 @@ public class XmppConnectionService extends Service { getContentResolver().registerContentObserver(ContactsContract.Contacts.CONTENT_URI, true, contactObserver); this.fileObserver.startWatching(); - if (Config.supportOpenPgp()) { this.pgpServiceConnection = new OpenPgpServiceConnection(getApplicationContext(), "org.sufficientlysecure.keychain", new OpenPgpServiceConnection.OnBound() { @Override @@ -811,6 +812,7 @@ public class XmppConnectionService extends Service { } catch (IllegalArgumentException e) { //ignored } + fileObserver.stopWatching(); super.onDestroy(); } @@ -1280,21 +1282,23 @@ public class XmppConnectionService extends Service { }); } - private void markFileDeleted(String uuid) { + private void markFileDeleted(final String path) { for (Conversation conversation : getConversations()) { - Message message = conversation.findMessageWithFileAndUuid(uuid); - if (message != null) { - 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); - } else { - updateConversationUi(); + conversation.findMessagesWithFiles(new Conversation.OnMessageFound() { + @Override + public void onMessageFound(Message message) { + DownloadableFile file = fileBackend.getFile(message); + if (file.getAbsolutePath().equals(path) && !file.exists()) { + 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); + } else { + updateConversationUi(); + } } } - return; - } + }); } } diff --git a/src/main/java/eu/siacs/conversations/utils/ConversationsFileObserver.java b/src/main/java/eu/siacs/conversations/utils/ConversationsFileObserver.java new file mode 100644 index 000000000..e6993bfe5 --- /dev/null +++ b/src/main/java/eu/siacs/conversations/utils/ConversationsFileObserver.java @@ -0,0 +1,72 @@ +package eu.siacs.conversations.utils; + + +import android.os.FileObserver; + +import java.io.File; +import java.util.ArrayList; +import java.util.List; +import java.util.Stack; + +/** + * Copyright (C) 2012 Bartek Przybylski + * Copyright (C) 2015 ownCloud Inc. + * Copyright (C) 2016 Daniel Gultsch + */ + +public abstract class ConversationsFileObserver { + + private final String path; + private final List<SingleFileObserver> mObservers = new ArrayList<>(); + + public ConversationsFileObserver(String path) { + this.path = path; + } + + public synchronized void startWatching() { + Stack<String> stack = new Stack<>(); + stack.push(path); + + while (!stack.empty()) { + String parent = stack.pop(); + mObservers.add(new SingleFileObserver(parent, FileObserver.DELETE)); + final File path = new File(parent); + final File[] files = path.listFiles(); + if (files == null) { + continue; + } + for(File file : files) { + if (file.isDirectory() && !file.getName().equals(".") && !file.getName().equals("..")) { + stack.push(file.getPath()); + } + } + } + for(FileObserver observer : mObservers) { + observer.startWatching(); + } + } + + public synchronized void stopWatching() { + for(FileObserver observer : mObservers) { + observer.stopWatching(); + } + mObservers.clear(); + } + + abstract public void onEvent(int event, String path); + + private class SingleFileObserver extends FileObserver { + private final String path; + + public SingleFileObserver(String path, int mask) { + super(path, mask); + this.path = path; + } + + @Override + public void onEvent(int event, String filename) { + ConversationsFileObserver.this.onEvent(event, path+'/'+filename); + } + + } +} |