mirror of
https://github.com/nextcloud/android.git
synced 2024-11-27 17:46:37 +03:00
Modify OwncloudFileObserver for enforcing watching the file when an external app cancelled the watch and added a handler for startWatching again
This commit is contained in:
parent
df8e9fa2c3
commit
a1f52fe73b
2 changed files with 88 additions and 52 deletions
|
@ -20,92 +20,129 @@ package com.owncloud.android.files;
|
|||
|
||||
import java.io.File;
|
||||
|
||||
import com.owncloud.android.datamodel.FileDataStorageManager;
|
||||
import com.owncloud.android.datamodel.OCFile;
|
||||
import com.owncloud.android.lib.common.operations.RemoteOperationResult;
|
||||
import com.owncloud.android.operations.SynchronizeFileOperation;
|
||||
import com.owncloud.android.lib.common.operations.RemoteOperationResult.ResultCode;
|
||||
import com.owncloud.android.ui.activity.ConflictsResolveActivity;
|
||||
import com.owncloud.android.utils.Log_OC;
|
||||
|
||||
import android.accounts.Account;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.os.FileObserver;
|
||||
import android.os.Handler;
|
||||
|
||||
import com.owncloud.android.datamodel.FileDataStorageManager;
|
||||
import com.owncloud.android.datamodel.OCFile;
|
||||
import com.owncloud.android.lib.common.operations.RemoteOperationResult;
|
||||
import com.owncloud.android.lib.common.operations.RemoteOperationResult.ResultCode;
|
||||
import com.owncloud.android.operations.SynchronizeFileOperation;
|
||||
import com.owncloud.android.ui.activity.ConflictsResolveActivity;
|
||||
import com.owncloud.android.utils.Log_OC;
|
||||
|
||||
public class OwnCloudFileObserver extends FileObserver {
|
||||
|
||||
private static int MASK = (FileObserver.MODIFY | FileObserver.CLOSE_WRITE);
|
||||
|
||||
private static int IN_IGNORE = 32768;
|
||||
|
||||
private static String TAG = OwnCloudFileObserver.class.getSimpleName();
|
||||
|
||||
|
||||
private String mPath;
|
||||
private int mMask;
|
||||
private Account mOCAccount;
|
||||
private Context mContext;
|
||||
private boolean mModified;
|
||||
private long mFileLastModified;
|
||||
private boolean mRestartWatching;
|
||||
private Handler mHandler;
|
||||
|
||||
|
||||
public OwnCloudFileObserver(String path, Account account, Context context) {
|
||||
super(path, MASK);
|
||||
public OwnCloudFileObserver(String path, Account account, Context context, Handler handler) {
|
||||
super(path, FileObserver.ALL_EVENTS);
|
||||
if (path == null)
|
||||
throw new IllegalArgumentException("NULL path argument received");
|
||||
throw new IllegalArgumentException("NULL path argument received");
|
||||
if (account == null)
|
||||
throw new IllegalArgumentException("NULL account argument received");
|
||||
throw new IllegalArgumentException("NULL account argument received");
|
||||
if (context == null)
|
||||
throw new IllegalArgumentException("NULL context argument received");
|
||||
mPath = path;
|
||||
mOCAccount = account;
|
||||
mContext = context;
|
||||
mContext = context;
|
||||
mModified = false;
|
||||
mFileLastModified = new File(path).lastModified();
|
||||
mHandler = handler;
|
||||
Log_OC.d(TAG, "Create Observer - FileLastModified: " + mFileLastModified);
|
||||
}
|
||||
|
||||
|
||||
|
||||
@Override
|
||||
public void onEvent(int event, String path) {
|
||||
Log_OC.d(TAG, "Got file modified with event " + event + " and path " + mPath + ((path != null) ? File.separator + path : ""));
|
||||
Log_OC.d(TAG, "Got file modified with event " + event + " and path " + mPath
|
||||
+ ((path != null) ? File.separator + path : ""));
|
||||
if ((event & MASK) == 0) {
|
||||
Log_OC.wtf(TAG, "Incorrect event " + event + " sent for file " + mPath + ((path != null) ? File.separator + path : "") +
|
||||
" with registered for " + mMask + " and original path " +
|
||||
mPath);
|
||||
Log_OC.wtf(TAG, "Incorrect event " + event + " sent for file " + mPath
|
||||
+ ((path != null) ? File.separator + path : "") + " with registered for " + mMask
|
||||
+ " and original path " + mPath);
|
||||
|
||||
// in case need start watching again
|
||||
if ((event & IN_IGNORE) != 0 && mRestartWatching) {
|
||||
mRestartWatching = false;
|
||||
|
||||
mHandler.postDelayed(new Runnable() {
|
||||
public void run() {
|
||||
startWatching();
|
||||
}
|
||||
}, 5000);
|
||||
|
||||
}
|
||||
} else {
|
||||
if ((event & FileObserver.MODIFY) != 0) {
|
||||
// file changed
|
||||
mModified = true;
|
||||
}
|
||||
// not sure if it's possible, but let's assume that both kind of events can be received at the same time
|
||||
// not sure if it's possible, but let's assume that both kind of
|
||||
// events can be received at the same time
|
||||
if ((event & FileObserver.CLOSE_WRITE) != 0) {
|
||||
// file closed
|
||||
if (mModified) {
|
||||
mModified = false;
|
||||
mRestartWatching = false;
|
||||
startSyncOperation();
|
||||
} else if (isFileUpdated()) {
|
||||
// if file has been modified but Modify event type has not
|
||||
// been launched
|
||||
mRestartWatching = true;
|
||||
mFileLastModified = new File(mPath).lastModified();
|
||||
Log_OC.d(TAG, "CLOSE_WRITE - New FileLastModified: " + mFileLastModified);
|
||||
startSyncOperation();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private void startSyncOperation() {
|
||||
FileDataStorageManager storageManager = new FileDataStorageManager(mOCAccount, mContext.getContentResolver());
|
||||
OCFile file = storageManager.getFileByLocalPath(mPath); // a fresh object is needed; many things could have occurred to the file since it was registered to observe
|
||||
// again, assuming that local files are linked to a remote file AT MOST, SOMETHING TO BE DONE;
|
||||
SynchronizeFileOperation sfo = new SynchronizeFileOperation(file,
|
||||
null,
|
||||
mOCAccount,
|
||||
true,
|
||||
mContext);
|
||||
// a fresh object is needed; many things could have occurred to the file
|
||||
// since it was registered to observe again, assuming that local files
|
||||
// are linked to a remote file AT MOST, SOMETHING TO BE DONE;
|
||||
OCFile file = storageManager.getFileByLocalPath(mPath);
|
||||
SynchronizeFileOperation sfo = new SynchronizeFileOperation(file, null, mOCAccount, true, mContext);
|
||||
RemoteOperationResult result = sfo.execute(storageManager, mContext);
|
||||
if (result.getCode() == ResultCode.SYNC_CONFLICT) {
|
||||
// ISSUE 5: if the user is not running the app (this is a service!), this can be very intrusive; a notification should be preferred
|
||||
// ISSUE 5: if the user is not running the app (this is a service!),
|
||||
// this can be very intrusive; a notification should be preferred
|
||||
Intent i = new Intent(mContext, ConflictsResolveActivity.class);
|
||||
i.setFlags(i.getFlags() | Intent.FLAG_ACTIVITY_NEW_TASK);
|
||||
i.putExtra(ConflictsResolveActivity.EXTRA_FILE, file);
|
||||
i.putExtra(ConflictsResolveActivity.EXTRA_ACCOUNT, mOCAccount);
|
||||
mContext.startActivity(i);
|
||||
}
|
||||
// TODO save other errors in some point where the user can inspect them later;
|
||||
// or maybe just toast them;
|
||||
// or nothing, very strange fails
|
||||
// TODO save other errors in some point where the user can inspect them
|
||||
// later;
|
||||
// or maybe just toast them;
|
||||
// or nothing, very strange fails
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if the timestamp of last file modification in local is more current
|
||||
* that the timestamp when setting observer to the file
|
||||
*
|
||||
* @return boolean: True if file is updated, False if not
|
||||
*/
|
||||
private boolean isFileUpdated() {
|
||||
Log_OC.d(TAG, "FileLastModified: " + mFileLastModified);
|
||||
return (new File(mPath).lastModified() > mFileLastModified);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -22,16 +22,6 @@ import java.io.File;
|
|||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import com.owncloud.android.MainApp;
|
||||
import com.owncloud.android.datamodel.FileDataStorageManager;
|
||||
import com.owncloud.android.datamodel.OCFile;
|
||||
import com.owncloud.android.db.ProviderMeta.ProviderTableMeta;
|
||||
import com.owncloud.android.files.OwnCloudFileObserver;
|
||||
import com.owncloud.android.operations.SynchronizeFileOperation;
|
||||
import com.owncloud.android.utils.FileStorageUtils;
|
||||
import com.owncloud.android.utils.Log_OC;
|
||||
|
||||
|
||||
import android.accounts.Account;
|
||||
import android.accounts.AccountManager;
|
||||
import android.app.Service;
|
||||
|
@ -41,8 +31,18 @@ import android.content.Intent;
|
|||
import android.content.IntentFilter;
|
||||
import android.database.Cursor;
|
||||
import android.os.Binder;
|
||||
import android.os.Handler;
|
||||
import android.os.IBinder;
|
||||
|
||||
import com.owncloud.android.MainApp;
|
||||
import com.owncloud.android.datamodel.FileDataStorageManager;
|
||||
import com.owncloud.android.datamodel.OCFile;
|
||||
import com.owncloud.android.db.ProviderMeta.ProviderTableMeta;
|
||||
import com.owncloud.android.files.OwnCloudFileObserver;
|
||||
import com.owncloud.android.operations.SynchronizeFileOperation;
|
||||
import com.owncloud.android.utils.FileStorageUtils;
|
||||
import com.owncloud.android.utils.Log_OC;
|
||||
|
||||
public class FileObserverService extends Service {
|
||||
|
||||
public final static int CMD_INIT_OBSERVED_LIST = 1;
|
||||
|
@ -58,6 +58,7 @@ public class FileObserverService extends Service {
|
|||
private static Map<String, OwnCloudFileObserver> mObserversMap;
|
||||
private static DownloadCompletedReceiverBis mDownloadReceiver;
|
||||
private IBinder mBinder = new LocalBinder();
|
||||
private Handler mHandler = new Handler();
|
||||
|
||||
public class LocalBinder extends Binder {
|
||||
FileObserverService getService() {
|
||||
|
@ -160,10 +161,7 @@ public class FileObserverService extends Service {
|
|||
String path = c.getString(c.getColumnIndex(ProviderTableMeta.FILE_STORAGE_PATH));
|
||||
if (path == null || path.length() <= 0)
|
||||
continue;
|
||||
OwnCloudFileObserver observer =
|
||||
new OwnCloudFileObserver( path,
|
||||
account,
|
||||
getApplicationContext());
|
||||
OwnCloudFileObserver observer = new OwnCloudFileObserver(path, account, getApplicationContext(), mHandler);
|
||||
mObserversMap.put(path, observer);
|
||||
if (new File(path).exists()) {
|
||||
observer.startWatching();
|
||||
|
@ -202,7 +200,8 @@ public class FileObserverService extends Service {
|
|||
/// the local file was never registered to observe before
|
||||
observer = new OwnCloudFileObserver( localPath,
|
||||
account,
|
||||
getApplicationContext());
|
||||
getApplicationContext(),
|
||||
mHandler);
|
||||
mObserversMap.put(localPath, observer);
|
||||
Log_OC.d(TAG, "Observer added for path " + localPath);
|
||||
|
||||
|
|
Loading…
Reference in a new issue