From: David A. Velasco Date: Wed, 14 Nov 2012 14:00:53 +0000 (+0100) Subject: Fixed lack of observance for files that are set as favourites when never were downloa... X-Git-Tag: oc-android-1.4.3~106 X-Git-Url: http://git.linex4red.de/pub/Android/ownCloud.git/commitdiff_plain/bd38627e14eeb75039be0c46717b7c7e8f783923?ds=inline;hp=--cc Fixed lack of observance for files that are set as favourites when never were download before --- bd38627e14eeb75039be0c46717b7c7e8f783923 diff --git a/src/com/owncloud/android/datamodel/FileDataStorageManager.java b/src/com/owncloud/android/datamodel/FileDataStorageManager.java index ca189407..c992af2c 100644 --- a/src/com/owncloud/android/datamodel/FileDataStorageManager.java +++ b/src/com/owncloud/android/datamodel/FileDataStorageManager.java @@ -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()); diff --git a/src/com/owncloud/android/files/OwnCloudFileObserver.java b/src/com/owncloud/android/files/OwnCloudFileObserver.java index 0093e7cf..1e0c176c 100644 --- a/src/com/owncloud/android/files/OwnCloudFileObserver.java +++ b/src/com/owncloud/android/files/OwnCloudFileObserver.java @@ -136,5 +136,13 @@ public class OwnCloudFileObserver extends FileObserver { Account account, FileObserverStatusListener.Status status); } + + public OCFile getOCFile() { + return mFile; + } + + public Account getAccount() { + return mOCAccount; + } } diff --git a/src/com/owncloud/android/files/services/FileObserverService.java b/src/com/owncloud/android/files/services/FileObserverService.java index 44713d11..effa520d 100644 --- a/src/com/owncloud/android/files/services/FileObserverService.java +++ b/src/com/owncloud/android/files/services/FileObserverService.java @@ -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; + 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) { - observer = mObservers.get(i); - if (observer.getPath().equals(path)) - duplicate = true; + 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(); diff --git a/src/com/owncloud/android/operations/SynchronizeFolderOperation.java b/src/com/owncloud/android/operations/SynchronizeFolderOperation.java index d24c41d7..08ddf7ee 100644 --- a/src/com/owncloud/android/operations/SynchronizeFolderOperation.java +++ b/src/com/owncloud/android/operations/SynchronizeFolderOperation.java @@ -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); } diff --git a/src/com/owncloud/android/ui/fragment/FileDetailFragment.java b/src/com/owncloud/android/ui/fragment/FileDetailFragment.java index 7ec8d7e2..76a387fd 100644 --- a/src/com/owncloud/android/ui/fragment/FileDetailFragment.java +++ b/src/com/owncloud/android/ui/fragment/FileDetailFragment.java @@ -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: {