Merge pull request #836 from owncloud/download_folder__fixing_recursive_cancellation

Fix of recursive cancellation
This commit is contained in:
David A. Velasco 2015-01-08 17:05:35 +01:00
commit eb6ec5dcf3
3 changed files with 54 additions and 21 deletions

View file

@ -96,9 +96,6 @@ public class FileDownloader extends Service implements OnDatatransferProgressLis
private NotificationCompat.Builder mNotificationBuilder; private NotificationCompat.Builder mNotificationBuilder;
private int mLastPercent; private int mLastPercent;
private Account mAccount;
private OCFile mFile;
public static String getDownloadAddedMessage() { public static String getDownloadAddedMessage() {
return FileDownloader.class.getName().toString() + DOWNLOAD_ADDED_MESSAGE; return FileDownloader.class.getName().toString() + DOWNLOAD_ADDED_MESSAGE;
@ -150,24 +147,24 @@ public class FileDownloader extends Service implements OnDatatransferProgressLis
Log_OC.e(TAG, "Not enough information provided in intent"); Log_OC.e(TAG, "Not enough information provided in intent");
return START_NOT_STICKY; return START_NOT_STICKY;
} else { } else {
mAccount = intent.getParcelableExtra(EXTRA_ACCOUNT); final Account account = intent.getParcelableExtra(EXTRA_ACCOUNT);
mFile = intent.getParcelableExtra(EXTRA_FILE); final OCFile file = intent.getParcelableExtra(EXTRA_FILE);
if (ACTION_CANCEL_FILE_DOWNLOAD.equals(intent.getAction())) { if (ACTION_CANCEL_FILE_DOWNLOAD.equals(intent.getAction())) {
new Thread(new Runnable() { new Thread(new Runnable() {
public void run() { public void run() {
// Cancel the download // Cancel the download
cancel(mAccount,mFile); cancel(account, file);
} }
}).start(); }).start();
} else { } else {
AbstractList<String> requestedDownloads = new Vector<String>(); // dvelasco: now this always contains just one element, but that can change in a near future (download of multiple selection) AbstractList<String> requestedDownloads = new Vector<String>(); // dvelasco: now this always contains just one element, but that can change in a near future (download of multiple selection)
String downloadKey = buildRemoteName(mAccount, mFile); String downloadKey = buildRemoteName(account, file);
try { try {
DownloadFileOperation newDownload = new DownloadFileOperation(mAccount, mFile); DownloadFileOperation newDownload = new DownloadFileOperation(account, file);
mPendingDownloads.putIfAbsent(downloadKey, newDownload); mPendingDownloads.putIfAbsent(downloadKey, newDownload);
newDownload.addDatatransferProgressListener(this); newDownload.addDatatransferProgressListener(this);
newDownload.addDatatransferProgressListener((FileDownloaderBinder) mBinder); newDownload.addDatatransferProgressListener((FileDownloaderBinder) mBinder);

View file

@ -165,13 +165,23 @@ public class SynchronizeFolderOperation extends SyncOperation {
sendBroadcastForNotifyingUIUpdate(result.isSuccess()); sendBroadcastForNotifyingUIUpdate(result.isSuccess());
} }
} }
if (mCancellationRequested.get()) {
throw new OperationCancelledException();
}
} catch (OperationCancelledException e) { } catch (OperationCancelledException e) {
result = new RemoteOperationResult(e); result = new RemoteOperationResult(e);
// cancel 'child' synchronizations // Needed in case that cancellation occurs before starting any download.
for (SyncOperation synchOp: mFoldersToWalkDown) { // If not, yellow arrow continues being shown.
((SynchronizeFolderOperation) synchOp).cancel(); sendBroadcastForNotifyingUIUpdate(false);
}
Intent intent = new Intent(mContext, FileDownloader.class);
intent.setAction(FileDownloader.ACTION_CANCEL_FILE_DOWNLOAD);
intent.putExtra(FileDownloader.EXTRA_ACCOUNT, mAccount);
intent.putExtra(FileDownloader.EXTRA_FILE, mLocalFolder);
mContext.startService(intent);
} }
return result; return result;
@ -275,7 +285,8 @@ public class SynchronizeFolderOperation extends SyncOperation {
* retrieved. * retrieved.
* @return 'True' when any change was made in the local data, 'false' otherwise * @return 'True' when any change was made in the local data, 'false' otherwise
*/ */
private void synchronizeData(ArrayList<Object> folderAndFiles, OwnCloudClient client) { private void synchronizeData(ArrayList<Object> folderAndFiles, OwnCloudClient client)
throws OperationCancelledException {
FileDataStorageManager storageManager = getStorageManager(); FileDataStorageManager storageManager = getStorageManager();
// parse data from remote folder // parse data from remote folder
@ -290,7 +301,13 @@ public class SynchronizeFolderOperation extends SyncOperation {
mFilesForDirectDownload.clear(); mFilesForDirectDownload.clear();
mFilesToSyncContentsWithoutUpload.clear(); mFilesToSyncContentsWithoutUpload.clear();
mFavouriteFilesToSyncContents.clear(); mFavouriteFilesToSyncContents.clear();
mFoldersToWalkDown.clear();
synchronized(mFoldersToWalkDown) {
if (mCancellationRequested.get()) {
throw new OperationCancelledException();
}
mFoldersToWalkDown.clear();
}
// get current data about local contents of the folder to synchronize // get current data about local contents of the folder to synchronize
List<OCFile> localFiles = storageManager.getFolderContent(mLocalFolder); List<OCFile> localFiles = storageManager.getFolderContent(mLocalFolder);
@ -352,7 +369,13 @@ public class SynchronizeFolderOperation extends SyncOperation {
mAccount, mAccount,
mCurrentSyncTime mCurrentSyncTime
); );
mFoldersToWalkDown.add(synchFolderOp);
synchronized(mFoldersToWalkDown) {
if (mCancellationRequested.get()) {
throw new OperationCancelledException();
}
mFoldersToWalkDown.add(synchFolderOp);
}
} else if (remoteFile.keepInSync()) { } else if (remoteFile.keepInSync()) {
/// prepare content synchronization for kept-in-sync files /// prepare content synchronization for kept-in-sync files
@ -387,7 +410,7 @@ public class SynchronizeFolderOperation extends SyncOperation {
} }
private void prepareOpsFromLocalKnowledge() { private void prepareOpsFromLocalKnowledge() throws OperationCancelledException {
List<OCFile> children = getStorageManager().getFolderContent(mLocalFolder); List<OCFile> children = getStorageManager().getFolderContent(mLocalFolder);
for (OCFile child : children) { for (OCFile child : children) {
/// classify file to sync/download contents later /// classify file to sync/download contents later
@ -399,7 +422,13 @@ public class SynchronizeFolderOperation extends SyncOperation {
mAccount, mAccount,
mCurrentSyncTime mCurrentSyncTime
); );
mFoldersToWalkDown.add(synchFolderOp);
synchronized(mFoldersToWalkDown) {
if (mCancellationRequested.get()) {
throw new OperationCancelledException();
}
mFoldersToWalkDown.add(synchFolderOp);
}
} else { } else {
/// prepare limited synchronization for regular files /// prepare limited synchronization for regular files
@ -541,6 +570,13 @@ public class SynchronizeFolderOperation extends SyncOperation {
*/ */
public void cancel() { public void cancel() {
mCancellationRequested.set(true); mCancellationRequested.set(true);
synchronized(mFoldersToWalkDown) {
// cancel 'child' synchronizations
for (SyncOperation synchOp : mFoldersToWalkDown) {
((SynchronizeFolderOperation) synchOp).cancel();
}
}
} }
public String getFolderPath() { public String getFolderPath() {

View file

@ -512,7 +512,7 @@ implements OnRemoteOperationListener, ComponentsGetter {
} }
private void onSynchronizeFolderOperationFinish(SynchronizeFolderOperation operation, RemoteOperationResult result) { private void onSynchronizeFolderOperationFinish(SynchronizeFolderOperation operation, RemoteOperationResult result) {
if (!result.isSuccess()){ if (!result.isSuccess() && result.getCode() != ResultCode.CANCELLED){
Toast t = Toast.makeText(this, ErrorMessageAdapter.getErrorCauseMessage(result, operation, getResources()), Toast t = Toast.makeText(this, ErrorMessageAdapter.getErrorCauseMessage(result, operation, getResources()),
Toast.LENGTH_LONG); Toast.LENGTH_LONG);
t.show(); t.show();