refactored deleted file detection to monitor entire sd card. fixes #1968
This commit is contained in:
		
							parent
							
								
									3d372cb339
								
							
						
					
					
						commit
						89a05265ea
					
				| @ -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; | ||||
| 			} | ||||
| 			}); | ||||
| 		} | ||||
| 	} | ||||
| 
 | ||||
|  | ||||
| @ -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); | ||||
|         } | ||||
| 
 | ||||
|     } | ||||
| } | ||||
		Loading…
	
		Reference in New Issue
	
	Block a user
	 Daniel Gultsch
						Daniel Gultsch