'Cancel folder download' cancels downloads of files already in the FileDownloadService

This commit is contained in:
jabarros 2014-12-16 14:02:23 +01:00
parent 5a4b0731f0
commit cec7baba5b
3 changed files with 100 additions and 36 deletions

View file

@ -29,6 +29,7 @@ import android.widget.Toast;
import com.owncloud.android.R;
import com.owncloud.android.datamodel.OCFile;
import com.owncloud.android.files.services.FileDownloader;
import com.owncloud.android.files.services.FileDownloader.FileDownloaderBinder;
import com.owncloud.android.files.services.FileUploader.FileUploaderBinder;
@ -304,8 +305,9 @@ public class FileOperationsHelper {
Intent intent = new Intent(mFileActivity, OperationsService.class);
intent.setAction(OperationsService.ACTION_CANCEL_SYNC_FOLDER);
intent.putExtra(OperationsService.EXTRA_ACCOUNT, account);
intent.putExtra(OperationsService.EXTRA_REMOTE_PATH, file.getRemotePath());
intent.putExtra(OperationsService.EXTRA_FILE, file);
mFileActivity.startService(intent);
}
}

View file

@ -21,6 +21,7 @@ package com.owncloud.android.files.services;
import java.io.File;
import java.io.IOException;
import java.util.AbstractList;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
@ -69,7 +70,9 @@ public class FileDownloader extends Service implements OnDatatransferProgressLis
public static final String EXTRA_ACCOUNT = "ACCOUNT";
public static final String EXTRA_FILE = "FILE";
public static final String ACTION_CANCEL_FILE_DOWNLOAD = "CANCEL_FILE_DOWNLOAD";
private static final String DOWNLOAD_ADDED_MESSAGE = "DOWNLOAD_ADDED";
private static final String DOWNLOAD_FINISH_MESSAGE = "DOWNLOAD_FINISH";
public static final String EXTRA_DOWNLOAD_RESULT = "RESULT";
@ -143,30 +146,39 @@ public class FileDownloader extends Service implements OnDatatransferProgressLis
) {
Log_OC.e(TAG, "Not enough information provided in intent");
return START_NOT_STICKY;
}
Account account = intent.getParcelableExtra(EXTRA_ACCOUNT);
OCFile file = intent.getParcelableExtra(EXTRA_FILE);
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(account, file);
try {
DownloadFileOperation newDownload = new DownloadFileOperation(account, file);
mPendingDownloads.putIfAbsent(downloadKey, newDownload);
newDownload.addDatatransferProgressListener(this);
newDownload.addDatatransferProgressListener((FileDownloaderBinder)mBinder);
requestedDownloads.add(downloadKey);
sendBroadcastNewDownload(newDownload);
} catch (IllegalArgumentException e) {
Log_OC.e(TAG, "Not enough information provided in intent: " + e.getMessage());
return START_NOT_STICKY;
}
if (requestedDownloads.size() > 0) {
Message msg = mServiceHandler.obtainMessage();
msg.arg1 = startId;
msg.obj = requestedDownloads;
mServiceHandler.sendMessage(msg);
} else {
Account account = intent.getParcelableExtra(EXTRA_ACCOUNT);
OCFile file = intent.getParcelableExtra(EXTRA_FILE);
if (ACTION_CANCEL_FILE_DOWNLOAD.equals(intent.getAction())) {
// Cancel the download
cancel(account,file);
} 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)
String downloadKey = buildRemoteName(account, file);
try {
DownloadFileOperation newDownload = new DownloadFileOperation(account, file);
mPendingDownloads.putIfAbsent(downloadKey, newDownload);
newDownload.addDatatransferProgressListener(this);
newDownload.addDatatransferProgressListener((FileDownloaderBinder) mBinder);
requestedDownloads.add(downloadKey);
sendBroadcastNewDownload(newDownload);
} catch (IllegalArgumentException e) {
Log_OC.e(TAG, "Not enough information provided in intent: " + e.getMessage());
return START_NOT_STICKY;
}
if (requestedDownloads.size() > 0) {
Message msg = mServiceHandler.obtainMessage();
msg.arg1 = startId;
msg.obj = requestedDownloads;
mServiceHandler.sendMessage(msg);
}
}
}
return START_NOT_STICKY;
@ -205,11 +217,11 @@ public class FileDownloader extends Service implements OnDatatransferProgressLis
* Map of listeners that will be reported about progress of downloads from a {@link FileDownloaderBinder} instance
*/
private Map<String, OnDatatransferProgressListener> mBoundListeners = new HashMap<String, OnDatatransferProgressListener>();
/**
* Cancels a pending or current download of a remote file.
*
*
* @param account Owncloud account where the remote file is stored.
* @param file A file in the queue of pending downloads
*/
@ -555,4 +567,45 @@ public class FileDownloader extends Service implements OnDatatransferProgressLis
sendStickyBroadcast(added);
}
/**
* Cancel operation
* @param account Owncloud account where the remote file is stored.
* @param file File OCFile
*/
public void cancel(Account account, OCFile file){
if(Looper.myLooper() == Looper.getMainLooper()) {
Log_OC.d(TAG, "Current Thread is Main Thread.");
} else {
Log_OC.d(TAG, "Current Thread is NOT Main Thread.");
}
DownloadFileOperation download = null;
String targetKey = buildRemoteName(account, file);
ArrayList<String> keyItems = new ArrayList<String>();
synchronized (mPendingDownloads) {
if (file.isFolder()) {
Log_OC.d(TAG, "Folder download. Canceling pending downloads (from folder)");
Iterator<String> it = mPendingDownloads.keySet().iterator();
boolean found = false;
while (it.hasNext()) {
String keyDownloadOperation = it.next();
found = keyDownloadOperation.startsWith(targetKey);
if (found) {
keyItems.add(keyDownloadOperation);
}
}
} else {
Log_OC.d(TAG, "Canceling file download");
keyItems.add(buildRemoteName(account, file));
}
}
for (String item: keyItems) {
download = mPendingDownloads.remove(item);
Log_OC.d(TAG, "Key removed: " + item);
if (download != null) {
download.cancel();
}
}
}
}

View file

@ -27,6 +27,7 @@ import com.owncloud.android.MainApp;
import com.owncloud.android.R;
import com.owncloud.android.datamodel.FileDataStorageManager;
import com.owncloud.android.datamodel.OCFile;
import com.owncloud.android.files.services.FileDownloader;
import com.owncloud.android.lib.common.OwnCloudAccount;
import com.owncloud.android.lib.common.OwnCloudClient;
import com.owncloud.android.lib.common.OwnCloudClientManagerFactory;
@ -83,7 +84,8 @@ public class OperationsService extends Service {
public static final String EXTRA_SYNC_FILE_CONTENTS = "SYNC_FILE_CONTENTS";
public static final String EXTRA_RESULT = "RESULT";
public static final String EXTRA_NEW_PARENT_PATH = "NEW_PARENT_PATH";
public static final String EXTRA_FILE = "FILE";
// TODO review if ALL OF THEM are necessary
public static final String EXTRA_SUCCESS_IF_ABSENT = "SUCCESS_IF_ABSENT";
public static final String EXTRA_USERNAME = "USERNAME";
@ -185,15 +187,15 @@ public class OperationsService extends Service {
mSyncFolderHandler.sendMessage(msg);
}
} else if (ACTION_CANCEL_SYNC_FOLDER.equals(intent.getAction())) {
if (!intent.hasExtra(EXTRA_ACCOUNT) || !intent.hasExtra(EXTRA_REMOTE_PATH)) {
if (!intent.hasExtra(EXTRA_ACCOUNT) || !intent.hasExtra(EXTRA_FILE)) {
Log_OC.e(TAG, "Not enough information provided in intent");
return START_NOT_STICKY;
}
Account account = intent.getParcelableExtra(EXTRA_ACCOUNT);
String remotePath = intent.getStringExtra(EXTRA_REMOTE_PATH);
OCFile file = intent.getParcelableExtra(EXTRA_FILE);
// Cancel operation
mSyncFolderHandler.cancel(account,remotePath);
mSyncFolderHandler.cancel(account,file);
} else {
Message msg = mOperationsHandler.obtainMessage();
msg.arg1 = startId;
@ -444,16 +446,23 @@ public class OperationsService extends Service {
* Cancels a pending or current sync operation.
*
* @param account Owncloud account where the remote file is stored.
* @param remotePath A remote file path
* @param file File
*/
public void cancel(Account account, String remotePath) {
public void cancel(Account account, OCFile file) {
SynchronizeFolderOperation syncOperation = null;
synchronized (mPendingOperations) {
syncOperation = mPendingOperations.remove(buildRemoteName(account, remotePath));
syncOperation = mPendingOperations.remove(buildRemoteName(account, file.getRemotePath()));
}
if (syncOperation != null) {
syncOperation.cancel();
}
Intent intent = new Intent( MainApp.getAppContext(), FileDownloader.class);
intent.setAction(FileDownloader.ACTION_CANCEL_FILE_DOWNLOAD);
intent.putExtra(FileDownloader.EXTRA_ACCOUNT, account);
intent.putExtra(FileDownloader.EXTRA_FILE, file);
MainApp.getAppContext().startService(intent);
}
/**