aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDaniel Gultsch <daniel@gultsch.de>2016-07-23 16:12:45 +0200
committerDaniel Gultsch <daniel@gultsch.de>2016-07-23 16:12:45 +0200
commit89a05265eaab5b52726268178beae0d5e9519e67 (patch)
treeafee2554a1ea096ccd7afac331ca75618507340f
parent3d372cb3394ce934cce2881f2bf428b302925431 (diff)
refactored deleted file detection to monitor entire sd card. fixes #1968
-rw-r--r--src/main/java/eu/siacs/conversations/services/XmppConnectionService.java42
-rw-r--r--src/main/java/eu/siacs/conversations/utils/ConversationsFileObserver.java72
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 766b1473..b6d073db 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;
@@ -70,6 +70,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;
@@ -91,6 +92,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;
@@ -211,14 +213,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() {
@@ -768,7 +770,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
@@ -814,6 +815,7 @@ public class XmppConnectionService extends Service {
} catch (IllegalArgumentException e) {
//ignored
}
+ fileObserver.stopWatching();
super.onDestroy();
}
@@ -1284,21 +1286,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 00000000..e6993bfe
--- /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);
+ }
+
+ }
+}