aboutsummaryrefslogtreecommitdiffstats
path: root/src/main/java/de/thedevstack/conversationsplus
diff options
context:
space:
mode:
authorsteckbrief <steckbrief@chefmail.de>2016-04-23 22:50:54 +0200
committersteckbrief <steckbrief@chefmail.de>2016-04-23 22:50:54 +0200
commitb789ace386ef3cfe6e0c3834b2a425813f702f43 (patch)
tree7c9e3a28af017be1689648f4e27d2c08cea7a2dc /src/main/java/de/thedevstack/conversationsplus
parentab82801448ed2e89e1387235f74ff37818767e2b (diff)
Fixes FS#204: Observe all used directories
- Implementing the FileObserver in a separate class, with mask to watch only deletions not everything - Add observation of all directories which could contain a sent/received file - Change observers if the folder names are changed via settings - markMessage method moved from XmppConnectionService to MessageUtil
Diffstat (limited to 'src/main/java/de/thedevstack/conversationsplus')
-rw-r--r--src/main/java/de/thedevstack/conversationsplus/ConversationsPlusApplication.java3
-rw-r--r--src/main/java/de/thedevstack/conversationsplus/entities/Conversation.java1
-rw-r--r--src/main/java/de/thedevstack/conversationsplus/persistance/FileBackend.java42
-rw-r--r--src/main/java/de/thedevstack/conversationsplus/persistance/observers/FileDeletionObserver.java45
-rw-r--r--src/main/java/de/thedevstack/conversationsplus/services/XmppConnectionService.java43
-rw-r--r--src/main/java/de/thedevstack/conversationsplus/ui/SettingsActivity.java8
-rw-r--r--src/main/java/de/thedevstack/conversationsplus/utils/MessageUtil.java13
-rw-r--r--src/main/java/de/thedevstack/conversationsplus/utils/XmppConnectionServiceAccessor.java31
8 files changed, 138 insertions, 48 deletions
diff --git a/src/main/java/de/thedevstack/conversationsplus/ConversationsPlusApplication.java b/src/main/java/de/thedevstack/conversationsplus/ConversationsPlusApplication.java
index d2eb77b7..a9f0c6ad 100644
--- a/src/main/java/de/thedevstack/conversationsplus/ConversationsPlusApplication.java
+++ b/src/main/java/de/thedevstack/conversationsplus/ConversationsPlusApplication.java
@@ -9,7 +9,6 @@ import java.io.File;
import de.thedevstack.conversationsplus.persistance.FileBackend;
import de.thedevstack.conversationsplus.utils.ImageUtil;
-import de.thedevstack.conversationsplus.R;
import de.thedevstack.conversationsplus.utils.SerialSingleThreadExecutor;
/**
@@ -32,7 +31,7 @@ public class ConversationsPlusApplication extends Application {
ConversationsPlusApplication.instance = this;
ConversationsPlusPreferences.init(PreferenceManager.getDefaultSharedPreferences(getAppContext()));
ImageUtil.initBitmapCache();
- FileBackend.createNoMedia();
+ FileBackend.init();
}
/**
diff --git a/src/main/java/de/thedevstack/conversationsplus/entities/Conversation.java b/src/main/java/de/thedevstack/conversationsplus/entities/Conversation.java
index 9e9366d7..bfd00b5d 100644
--- a/src/main/java/de/thedevstack/conversationsplus/entities/Conversation.java
+++ b/src/main/java/de/thedevstack/conversationsplus/entities/Conversation.java
@@ -140,6 +140,7 @@ public class Conversation extends AbstractEntity implements Blockable {
}
public Message findMessageWithFileAndUuid(final String uuid) {
+ // TODO Implement this method to find a message by a real filename - not uuid
synchronized (this.messages) {
for (final Message message : this.messages) {
if ((message.getType() == Message.TYPE_IMAGE || message.getType() == Message.TYPE_FILE)
diff --git a/src/main/java/de/thedevstack/conversationsplus/persistance/FileBackend.java b/src/main/java/de/thedevstack/conversationsplus/persistance/FileBackend.java
index 5645caf6..9f7e473e 100644
--- a/src/main/java/de/thedevstack/conversationsplus/persistance/FileBackend.java
+++ b/src/main/java/de/thedevstack/conversationsplus/persistance/FileBackend.java
@@ -21,6 +21,7 @@ import de.thedevstack.android.logcat.Logging;
import de.thedevstack.conversationsplus.ConversationsPlusApplication;
import de.thedevstack.conversationsplus.ConversationsPlusPreferences;
import de.thedevstack.conversationsplus.exceptions.FileCopyException;
+import de.thedevstack.conversationsplus.persistance.observers.FileDeletionObserver;
import de.thedevstack.conversationsplus.utils.StreamUtil;
import de.thedevstack.conversationsplus.Config;
import de.thedevstack.conversationsplus.R;
@@ -30,8 +31,34 @@ import de.thedevstack.conversationsplus.services.XmppConnectionService;
public class FileBackend {
private static final SimpleDateFormat imageDateFormat = new SimpleDateFormat("yyyyMMdd_HHmmssSSS", Locale.US);
+ private static FileBackend INSTANCE;
- public static void createNoMedia() {
+ private FileDeletionObserver privateFilesDirectoryObserver;
+ private FileDeletionObserver privateFilesImageDirectoryObserver;
+ private FileDeletionObserver conversationsFilesDirectoryObserver;
+ private FileDeletionObserver conversationsImagesDirectoryObserver;
+
+ public static void init() {
+ if (null == INSTANCE) {
+ INSTANCE = new FileBackend();
+ }
+ INSTANCE.initFileObservers();
+ INSTANCE.createNoMedia();
+ }
+
+ private void initFileObservers() {
+ this.privateFilesDirectoryObserver = new FileDeletionObserver(FileBackend.getPrivateFileDirectoryPath());
+ this.privateFilesImageDirectoryObserver = new FileDeletionObserver(FileBackend.getConversationsFileDirectory());
+ this.conversationsFilesDirectoryObserver = new FileDeletionObserver(FileBackend.getConversationsImageDirectory());
+ this.conversationsImagesDirectoryObserver = new FileDeletionObserver(FileBackend.getPrivateImageDirectoryPath());
+
+ this.privateFilesDirectoryObserver.startWatching();
+ this.privateFilesImageDirectoryObserver.startWatching();
+ this.conversationsFilesDirectoryObserver.startWatching();
+ this.conversationsImagesDirectoryObserver.startWatching();
+ }
+
+ private void createNoMedia() {
final File nomedia = new File(getConversationsFileDirectory()+".nomedia");
if (!nomedia.exists()) {
try {
@@ -42,6 +69,19 @@ public class FileBackend {
}
}
+ public static void onFileTransferFolderChanged() {
+ INSTANCE.conversationsFilesDirectoryObserver.stopWatching();
+ INSTANCE.conversationsFilesDirectoryObserver = new FileDeletionObserver(FileBackend.getConversationsFileDirectory());
+ INSTANCE.conversationsFilesDirectoryObserver.startWatching();
+ INSTANCE.createNoMedia();
+ }
+
+ public static void onImageTransferFolderChanged() {
+ INSTANCE.conversationsImagesDirectoryObserver.stopWatching();
+ INSTANCE.conversationsImagesDirectoryObserver = new FileDeletionObserver(FileBackend.getConversationsImageDirectory());
+ INSTANCE.conversationsImagesDirectoryObserver.startWatching();
+ }
+
public static void updateMediaScanner(File file, XmppConnectionService xmppConnectionService) {
if (file.getAbsolutePath().startsWith(getConversationsImageDirectory())) {
Intent intent = new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE);
diff --git a/src/main/java/de/thedevstack/conversationsplus/persistance/observers/FileDeletionObserver.java b/src/main/java/de/thedevstack/conversationsplus/persistance/observers/FileDeletionObserver.java
new file mode 100644
index 00000000..3534ccd2
--- /dev/null
+++ b/src/main/java/de/thedevstack/conversationsplus/persistance/observers/FileDeletionObserver.java
@@ -0,0 +1,45 @@
+package de.thedevstack.conversationsplus.persistance.observers;
+
+import android.os.FileObserver;
+
+import de.thedevstack.conversationsplus.entities.Conversation;
+import de.thedevstack.conversationsplus.entities.Message;
+import de.thedevstack.conversationsplus.entities.Transferable;
+import de.thedevstack.conversationsplus.entities.TransferablePlaceholder;
+import de.thedevstack.conversationsplus.utils.MessageUtil;
+import de.thedevstack.conversationsplus.utils.UiUpdateHelper;
+import de.thedevstack.conversationsplus.utils.XmppConnectionServiceAccessor;
+
+/**
+ * Observer to mark messages containing files which are deleted.
+ */
+public class FileDeletionObserver extends FileObserver {
+ public FileDeletionObserver(String path) {
+ super(path, FileObserver.DELETE);
+ }
+
+ @Override
+ public void onEvent(int event, String path) {
+ if (null != path) {
+ markFileDeleted(path.split("\\.")[0]);
+ }
+ }
+
+ private void markFileDeleted(String uuid) {
+ if (null != XmppConnectionServiceAccessor.xmppConnectionService) {
+ for (Conversation conversation : XmppConnectionServiceAccessor.xmppConnectionService.getConversations()) {
+ Message message = conversation.findMessageWithFileAndUuid(uuid);
+ if (message != null) {
+ 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) {
+ MessageUtil.markMessage(message, Message.STATUS_SEND_FAILED);
+ } else {
+ UiUpdateHelper.updateConversationUi();
+ }
+ return;
+ }
+ }
+ }
+ }
+}
diff --git a/src/main/java/de/thedevstack/conversationsplus/services/XmppConnectionService.java b/src/main/java/de/thedevstack/conversationsplus/services/XmppConnectionService.java
index b7b4db2c..cf587efe 100644
--- a/src/main/java/de/thedevstack/conversationsplus/services/XmppConnectionService.java
+++ b/src/main/java/de/thedevstack/conversationsplus/services/XmppConnectionService.java
@@ -7,7 +7,6 @@ import android.app.Service;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
-import android.content.SharedPreferences;
import android.database.ContentObserver;
import android.graphics.Bitmap;
import android.media.AudioManager;
@@ -17,13 +16,11 @@ import android.net.Uri;
import android.os.Binder;
import android.os.Build;
import android.os.Bundle;
-import android.os.FileObserver;
import android.os.IBinder;
import android.os.Looper;
import android.os.PowerManager;
import android.os.PowerManager.WakeLock;
import android.os.SystemClock;
-import android.preference.PreferenceManager;
import android.provider.ContactsContract;
import android.security.KeyChain;
import android.util.DisplayMetrics;
@@ -66,6 +63,7 @@ import de.thedevstack.conversationsplus.utils.FileUtils;
import de.thedevstack.conversationsplus.utils.ImageUtil;
import de.thedevstack.conversationsplus.utils.MessageUtil;
import de.thedevstack.conversationsplus.utils.UiUpdateHelper;
+import de.thedevstack.conversationsplus.utils.XmppConnectionServiceAccessor;
import de.thedevstack.conversationsplus.utils.XmppSendUtil;
import de.tzur.conversations.Settings;
import de.thedevstack.conversationsplus.Config;
@@ -204,16 +202,6 @@ public class XmppConnectionService extends Service implements OnPhoneContactsLoa
private MessageArchiveService mMessageArchiveService = new MessageArchiveService(this);
private PushManagementService mPushManagementService = new PushManagementService(this);
private OnConversationUpdate mOnConversationUpdate = null;
- private final FileObserver fileObserver = new FileObserver(
- FileBackend.getConversationsImageDirectory()) {
-
- @Override
- public void onEvent(int event, String path) {
- if (event == FileObserver.DELETE) {
- markFileDeleted(path.split("\\.")[0]);
- }
- }
- };
private final OnJinglePacketReceived jingleListener = new OnJinglePacketReceived() {
@Override
@@ -665,7 +653,6 @@ public class XmppConnectionService extends Service implements OnPhoneContactsLoa
restoreFromDatabase();
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() {
@@ -690,6 +677,7 @@ public class XmppConnectionService extends Service implements OnPhoneContactsLoa
toggleForegroundService();
updateUnreadCountBadge();
UiUpdateHelper.initXmppConnectionService(this);
+ XmppConnectionServiceAccessor.initXmppConnectionService(this);
toggleScreenEventReceiver();
}
@@ -1177,24 +1165,6 @@ public class XmppConnectionService extends Service implements OnPhoneContactsLoa
});
}
- private void markFileDeleted(String uuid) {
- for (Conversation conversation : getConversations()) {
- Message message = conversation.findMessageWithFileAndUuid(uuid);
- if (message != null) {
- if (!FileBackend.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();
- }
- }
- return;
- }
- }
- }
-
public void populateWithOrderedConversations(final List<Conversation> list) {
populateWithOrderedConversations(list, true);
}
@@ -2412,14 +2382,7 @@ public class XmppConnectionService extends Service implements OnPhoneContactsLoa
}
public void markMessage(Message message, int status) {
- if (status == Message.STATUS_SEND_FAILED
- && (message.getStatus() == Message.STATUS_SEND_RECEIVED || message
- .getStatus() == Message.STATUS_SEND_DISPLAYED)) {
- return;
- }
- message.setStatus(status);
- databaseBackend.updateMessage(message);
- updateConversationUi();
+ MessageUtil.markMessage(message, status);
}
public int unreadCount() {
diff --git a/src/main/java/de/thedevstack/conversationsplus/ui/SettingsActivity.java b/src/main/java/de/thedevstack/conversationsplus/ui/SettingsActivity.java
index 35816cff..84eb7016 100644
--- a/src/main/java/de/thedevstack/conversationsplus/ui/SettingsActivity.java
+++ b/src/main/java/de/thedevstack/conversationsplus/ui/SettingsActivity.java
@@ -9,13 +9,10 @@ import android.content.SharedPreferences.OnSharedPreferenceChangeListener;
import android.content.pm.PackageManager;
import android.os.Build;
import android.os.Bundle;
-import android.preference.CheckBoxPreference;
import android.preference.ListPreference;
import android.preference.Preference;
import android.preference.PreferenceCategory;
import android.preference.PreferenceManager;
-import android.preference.PreferenceScreen;
-import android.util.Log;
import android.widget.Toast;
import java.security.KeyStoreException;
@@ -31,7 +28,6 @@ import de.tzur.conversations.Settings;
import de.thedevstack.conversationsplus.R;
import de.thedevstack.conversationsplus.entities.Account;
import de.thedevstack.conversationsplus.persistance.FileBackend;
-import de.thedevstack.conversationsplus.services.ExportLogsService;
import de.thedevstack.conversationsplus.xmpp.XmppConnection;
import github.ankushsachdeva.emojicon.EmojiconHandler;
@@ -187,7 +183,9 @@ public class SettingsActivity extends XmppActivity implements
} else if ("parse_emoticons".equals(name)) {
EmojiconHandler.setParseEmoticons(Settings.PARSE_EMOTICONS);
} else if ("file_transfer_folder".equals(name)) {
- FileBackend.createNoMedia();
+ FileBackend.onFileTransferFolderChanged();
+ } else if ("img_transfer_folder".equals(name)) {
+ FileBackend.onImageTransferFolderChanged();
}
}
diff --git a/src/main/java/de/thedevstack/conversationsplus/utils/MessageUtil.java b/src/main/java/de/thedevstack/conversationsplus/utils/MessageUtil.java
index 6a668938..7fbc2d94 100644
--- a/src/main/java/de/thedevstack/conversationsplus/utils/MessageUtil.java
+++ b/src/main/java/de/thedevstack/conversationsplus/utils/MessageUtil.java
@@ -6,8 +6,10 @@ import java.net.URL;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
+import de.thedevstack.conversationsplus.ConversationsPlusApplication;
import de.thedevstack.conversationsplus.entities.DownloadableFile;
import de.thedevstack.conversationsplus.entities.Message;
+import de.thedevstack.conversationsplus.persistance.DatabaseBackend;
import de.thedevstack.conversationsplus.persistance.FileBackend;
/**
@@ -15,6 +17,17 @@ import de.thedevstack.conversationsplus.persistance.FileBackend;
*/
public final class MessageUtil {
+ public static void markMessage(Message message, int status) {
+ if (status == Message.STATUS_SEND_FAILED
+ && (message.getStatus() == Message.STATUS_SEND_RECEIVED || message
+ .getStatus() == Message.STATUS_SEND_DISPLAYED)) {
+ return;
+ }
+ message.setStatus(status);
+ DatabaseBackend.getInstance(ConversationsPlusApplication.getAppContext()).updateMessage(message);
+ UiUpdateHelper.updateConversationUi();
+ }
+
public static boolean wasHighlightedOrPrivate(final Message message) {
final String nick = message.getConversation().getMucOptions().getActualNick();
final Pattern highlight = generateNickHighlightPattern(nick);
diff --git a/src/main/java/de/thedevstack/conversationsplus/utils/XmppConnectionServiceAccessor.java b/src/main/java/de/thedevstack/conversationsplus/utils/XmppConnectionServiceAccessor.java
new file mode 100644
index 00000000..1f1d7cf4
--- /dev/null
+++ b/src/main/java/de/thedevstack/conversationsplus/utils/XmppConnectionServiceAccessor.java
@@ -0,0 +1,31 @@
+package de.thedevstack.conversationsplus.utils;
+
+import de.thedevstack.android.logcat.Logging;
+import de.thedevstack.conversationsplus.services.XmppConnectionService;
+
+/**
+ * Accessor utility to access XmppConnectionService without having to pass the XmppConnectionService every time.
+ */
+public final class XmppConnectionServiceAccessor {
+ public static XmppConnectionService xmppConnectionService;
+
+ /**
+ * Initializes the XmppConnectionService.
+ * This method needs to be called once in XmppConnectionService#onCreate.
+ * @param xmppConnectionService
+ */
+ public static void initXmppConnectionService(XmppConnectionService xmppConnectionService) {
+ if (null == XmppConnectionServiceAccessor.xmppConnectionService) {
+ XmppConnectionServiceAccessor.xmppConnectionService = xmppConnectionService;
+ } else {
+ Logging.e("XmppConnectionServiceAccessor", "XMPP Connection Service already instantiated.");
+ }
+ }
+
+ /**
+ * Avoid instantiation
+ */
+ private XmppConnectionServiceAccessor() {
+ // avoid instantiation
+ }
+}