Fixed lack of observance for files that are set as favourites when never were download before

This commit is contained in:
David A. Velasco 2012-11-14 15:00:53 +01:00
parent b12ca42b45
commit bd38627e14
5 changed files with 140 additions and 47 deletions

View file

@ -123,7 +123,7 @@ public class FileDataStorageManager implements DataStorageManager {
if (fileExists(file.getRemotePath())) {
OCFile oldFile = getFileByPath(file.getRemotePath());
if (file.getStoragePath() == null && oldFile.getStoragePath() != null)
if (file.getStoragePath() == null && oldFile.isDown())
file.setStoragePath(oldFile.getStoragePath());
if (!file.isDirectory());
cv.put(ProviderTableMeta.FILE_STORAGE_PATH, file.getStoragePath());

View file

@ -136,5 +136,13 @@ public class OwnCloudFileObserver extends FileObserver {
Account account,
FileObserverStatusListener.Status status);
}
public OCFile getOCFile() {
return mFile;
}
public Account getAccount() {
return mOCAccount;
}
}

View file

@ -22,12 +22,13 @@ import java.io.File;
import java.util.ArrayList;
import java.util.List;
import com.owncloud.android.AccountUtils;
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.files.OwnCloudFileObserver.FileObserverStatusListener;
import com.owncloud.android.ui.activity.ConflictsResolveActivity;
import com.owncloud.android.utils.FileStorageUtils;
import android.accounts.Account;
import android.accounts.AccountManager;
@ -44,7 +45,8 @@ import android.util.Log;
public class FileObserverService extends Service implements FileObserverStatusListener {
public final static String KEY_FILE_CMD = "KEY_FILE_CMD";
public final static String KEY_CMD_ARG = "KEY_CMD_ARG";
public final static String KEY_CMD_ARG_FILE = "KEY_CMD_ARG_FILE";
public final static String KEY_CMD_ARG_ACCOUNT = "KEY_CMD_ARG_ACCOUNT";
public final static int CMD_INIT_OBSERVED_LIST = 1;
public final static int CMD_ADD_OBSERVED_FILE = 2;
@ -87,13 +89,16 @@ public class FileObserverService extends Service implements FileObserverStatusLi
initializeObservedList();
break;
case CMD_ADD_OBSERVED_FILE:
addObservedFile(intent.getStringExtra(KEY_CMD_ARG));
addObservedFile( (OCFile)intent.getParcelableExtra(KEY_CMD_ARG_FILE),
(Account)intent.getParcelableExtra(KEY_CMD_ARG_ACCOUNT));
break;
case CMD_DEL_OBSERVED_FILE:
removeObservedFile(intent.getStringExtra(KEY_CMD_ARG));
removeObservedFile( (OCFile)intent.getParcelableExtra(KEY_CMD_ARG_FILE),
(Account)intent.getParcelableExtra(KEY_CMD_ARG_ACCOUNT));
break;
case CMD_ADD_DOWNLOADING_FILE:
addDownloadingFile(intent.getStringExtra(KEY_CMD_ARG));
addDownloadingFile( (OCFile)intent.getParcelableExtra(KEY_CMD_ARG_FILE),
(Account)intent.getParcelableExtra(KEY_CMD_ARG_ACCOUNT));
break;
default:
Log.wtf(TAG, "Incorrect key given");
@ -145,65 +150,137 @@ public class FileObserverService extends Service implements FileObserverStatusLi
c.close();
}
private void addObservedFile(String path) {
if (path == null) return;
/**
* Registers the local copy of a remote file to be observed for local changes,
* an automatically updated in the ownCloud server.
*
* If there is no local copy of the remote file, a request to download it is send
* to the FileDownloader service. The observation is delayed until the download
* is finished.
*
* @param file Object representing a remote file which local copy must be observed.
* @param account OwnCloud account containing file.
*/
private void addObservedFile(OCFile file, Account account) {
if (file == null) {
Log.e(TAG, "Trying to observe a NULL file");
return;
}
if (mObservers == null) {
// this is very rare case when service was killed by system
// and observers list was deleted in that procedure
initializeObservedList();
}
boolean duplicate = false;
OwnCloudFileObserver observer = null;
for (int i = 0; i < mObservers.size(); ++i) {
observer = mObservers.get(i);
if (observer.getPath().equals(path))
duplicate = true;
observer.setContext(getApplicationContext());
String localPath = file.getStoragePath();
if (!file.isDown()) {
// this is a file downloading / to be download for the first time
localPath = FileStorageUtils.getDefaultSavePathFor(account.name, file);
}
OwnCloudFileObserver tmpObserver = null, observer = null;
for (int i = 0; i < mObservers.size(); ++i) {
tmpObserver = mObservers.get(i);
if (tmpObserver.getPath().equals(localPath)) {
observer = tmpObserver;
}
tmpObserver.setContext(getApplicationContext()); // 'refreshing' context to all the observers? why?
}
if (observer == null) {
/// the local file was never registered to observe before
observer = new OwnCloudFileObserver(localPath, OwnCloudFileObserver.CHANGES_ONLY);
//Account account = AccountUtils.getCurrentOwnCloudAccount(getApplicationContext());
observer.setAccount(account);
FileDataStorageManager storage =
new FileDataStorageManager(account, getContentResolver()); // I don't trust in this resolver's life span...
observer.setStorageManager(storage);
//observer.setOCFile(storage.getFileByLocalPath(path)); // ISSUE 10 - the fix in FileDetailsFragment to avoid path == null was not enough; it the file was never down before, this sets a NULL OCFile in the observer
observer.setOCFile(file);
observer.addObserverStatusListener(this);
observer.setContext(getApplicationContext());
} else {
/* LET'S IGNORE THAT, CURRENTLY, A LOCAL FILE CAN BE LINKED TO DIFFERENT FILES IN OWNCLOUD;
* we should change that
*
/// the local file is already observed for some other OCFile(s)
observer.addOCFile(account, file); // OCFiles should have a reference to the account containing them to not be confused
*/
}
if (duplicate) return;
observer = new OwnCloudFileObserver(path, OwnCloudFileObserver.CHANGES_ONLY);
observer.setContext(getApplicationContext());
Account account = AccountUtils.getCurrentOwnCloudAccount(getApplicationContext());
observer.setAccount(account);
FileDataStorageManager storage =
new FileDataStorageManager(account, getContentResolver());
observer.setStorageManager(storage);
observer.setOCFile(storage.getFileByLocalPath(path)); // ISSUE 10 - the fix in FileDetailsFragment to avoid path == null was not enough; it the file was never down before, this sets a NULL OCFile in the observer
observer.addObserverStatusListener(this);
DownloadCompletedReceiver receiver = new DownloadCompletedReceiver(path, observer);
registerReceiver(receiver, new IntentFilter(FileDownloader.DOWNLOAD_FINISH_MESSAGE));
mObservers.add(observer);
Log.d(TAG, "Observer added for path " + path);
Log.d(TAG, "Observer added for path " + localPath);
if (!file.isDown()) {
// if the file is not down, it can't be observed for changes
DownloadCompletedReceiver receiver = new DownloadCompletedReceiver(localPath, observer);
registerReceiver(receiver, new IntentFilter(FileDownloader.DOWNLOAD_FINISH_MESSAGE));
Intent i = new Intent(this, FileDownloader.class);
i.putExtra(FileDownloader.EXTRA_ACCOUNT, account);
i.putExtra(FileDownloader.EXTRA_FILE, file);
startService(i);
} else {
observer.startWatching();
Log.d(TAG, "Started watching " + localPath);
}
}
private void removeObservedFile(String path) {
if (path == null) return;
/**
* Unregisters the local copy of a remote file to be observed for local changes.
*
* @param file Object representing a remote file which local copy must be not observed longer.
* @param account OwnCloud account containing file.
*/
private void removeObservedFile(OCFile file, Account account) {
if (file == null) {
Log.e(TAG, "Trying to unobserve a NULL file");
return;
}
if (mObservers == null) {
initializeObservedList();
}
String localPath = file.getStoragePath();
if (!file.isDown()) {
// this happens when a file not in the device is set to be kept synchronized, and quickly unset again,
// while the download is not finished
localPath = FileStorageUtils.getDefaultSavePathFor(account.name, file);
}
for (int i = 0; i < mObservers.size(); ++i) {
OwnCloudFileObserver observer = mObservers.get(i);
if (observer.getPath().equals(path)) {
if (observer.getPath().equals(localPath)) {
observer.stopWatching();
mObservers.remove(i);
Log.d(TAG, "Stopped watching " + path);
mObservers.remove(i); // assuming, again, that a local file can be only linked to only ONE remote file; currently false
if (!file.isDown()) {
// TODO unregister download receiver ;forget this until list of receivers is replaced for a single receiver
}
Log.d(TAG, "Stopped watching " + localPath);
break;
}
}
}
private void addDownloadingFile(String remotePath) {
}
/**
* Temporarily disables the observance of a file that is going to be download.
*
* @param file Object representing the remote file which local copy must not be observed temporarily.
* @param account OwnCloud account containing file.
*/
private void addDownloadingFile(OCFile file, Account account) {
OwnCloudFileObserver observer = null;
for (OwnCloudFileObserver o : mObservers) {
if (o.getRemotePath().equals(remotePath)) {
if (o.getRemotePath().equals(file.getRemotePath()) && o.getAccount().equals(account)) {
observer = o;
break;
}
}
if (observer == null) {
Log.e(TAG, "Couldn't find observer for remote file " + remotePath);
Log.e(TAG, "Couldn't find observer for remote file " + file.getRemotePath());
return;
}
observer.stopWatching();

View file

@ -213,7 +213,8 @@ public class SynchronizeFolderOperation extends RemoteOperation {
Log.d(TAG, "Disabling observation of remote file" + file.getRemotePath());
Intent intent = new Intent(mContext, FileObserverService.class);
intent.putExtra(FileObserverService.KEY_FILE_CMD, FileObserverService.CMD_ADD_DOWNLOADING_FILE);
intent.putExtra(FileObserverService.KEY_CMD_ARG, file.getRemotePath());
intent.putExtra(FileObserverService.KEY_CMD_ARG_FILE, file);
intent.putExtra(FileObserverService.KEY_CMD_ARG_ACCOUNT, mAccount);
mContext.startService(intent);
}

View file

@ -87,7 +87,6 @@ import com.owncloud.android.ui.activity.FileDisplayActivity;
import com.owncloud.android.ui.activity.TransferServiceGetter;
import com.owncloud.android.ui.dialog.EditNameDialog;
import com.owncloud.android.ui.dialog.EditNameDialog.EditNameDialogListener;
import com.owncloud.android.utils.FileStorageUtils;
import com.owncloud.android.utils.OwnCloudVersion;
import com.owncloud.android.R;
@ -311,26 +310,34 @@ public class FileDetailFragment extends SherlockFragment implements
mFile.setKeepInSync(cb.isChecked());
FileDataStorageManager fdsm = new FileDataStorageManager(mAccount, getActivity().getApplicationContext().getContentResolver());
fdsm.saveFile(mFile);
if (mFile.keepInSync()) {
/* NOT HERE
* now that FileObserverService is involved, the easiest way to coordinate it with the download service
* in every possible case is let the FileObserverService decide if the download should be started at
* this moment or not
*
* see changes at FileObserverService#addObservedFile
if (mFile.keepInSync()) {
onClick(getView().findViewById(R.id.fdDownloadBtn));
} else {
mContainerActivity.onFileStateChanged(); // put inside 'else' to not call it twice (here, and in the virtual click on fdDownloadBtn)
}
}*/
/// register the OCFile instance in the observer service to monitor local updates;
/// if necessary, the file is download
Intent intent = new Intent(getActivity().getApplicationContext(),
FileObserverService.class);
intent.putExtra(FileObserverService.KEY_FILE_CMD,
(cb.isChecked()?
FileObserverService.CMD_ADD_OBSERVED_FILE:
FileObserverService.CMD_DEL_OBSERVED_FILE));
String localPath = mFile.getStoragePath();
if (localPath == null || localPath.length() <= 0) {
localPath = FileStorageUtils.getDefaultSavePathFor(mAccount.name, mFile);
}
intent.putExtra(FileObserverService.KEY_CMD_ARG, localPath);
intent.putExtra(FileObserverService.KEY_CMD_ARG_FILE, mFile);
intent.putExtra(FileObserverService.KEY_CMD_ARG_ACCOUNT, mAccount);
Log.e(TAG, "starting observer service");
getActivity().startService(intent);
mContainerActivity.onFileStateChanged();
break;
}
case R.id.fdRenameBtn: {