android:icon="@drawable/ic_action_refresh"
android:orderInCategory="1" />
<item
+ android:id="@+id/action_cancel_sync"
+ android:title="@string/common_cancel_sync"
+ android:icon="@android:drawable/ic_menu_close_clear_cancel"
+ android:orderInCategory="1" />
+ <item
android:id="@+id/action_cancel_download"
android:title="@string/common_cancel_download"
android:icon="@android:drawable/ic_menu_close_clear_cancel"
<string name="common_yes">Yes</string>
<string name="common_no">No</string>
<string name="common_ok">OK</string>
- <string name="common_cancel_download">Cancel download</string>
- <string name="common_cancel_upload">Cancel upload</string>
+ <string name="common_cancel_sync">Cancel synchronization</string>
<string name="common_cancel">Cancel</string>
<string name="common_save_exit">Save & Exit</string>
<string name="common_error">Error</string>
* @param toHide List to save the options that must be shown in the menu.
*/
private void filter(List<Integer> toShow, List <Integer> toHide) {
+ boolean synchronizing = false;
+ if (mComponentsGetter != null && mFile != null && mAccount != null) {
+ OperationsServiceBinder opsBinder = mComponentsGetter.getOperationsServiceBinder();
+ FileUploaderBinder uploaderBinder = mComponentsGetter.getFileUploaderBinder();
+ FileDownloaderBinder downloaderBinder = mComponentsGetter.getFileDownloaderBinder();
+ synchronizing = (
+ // comparing local and remote
+ (opsBinder != null && opsBinder.isSynchronizing(mAccount, mFile.getRemotePath())) ||
+ // downloading
+ (downloaderBinder != null && downloaderBinder.isDownloading(mAccount, mFile)) ||
+ // uploading
+ (uploaderBinder != null && uploaderBinder.isUploading(mAccount, mFile))
+ );
+ }
+
+ /*
boolean downloading = false;
boolean uploading = false;
if (mComponentsGetter != null && mFile != null && mAccount != null) {
FileUploaderBinder uploaderBinder = mComponentsGetter.getFileUploaderBinder();
uploading = (uploaderBinder != null && uploaderBinder.isUploading(mAccount, mFile));
}
-
+ */
+
/// decision is taken for each possible action on a file in the menu
// DOWNLOAD
- if (mFile == null || mFile.isDown() || downloading || uploading) {
+ if (mFile == null || mFile.isDown() || synchronizing) {
toHide.add(R.id.action_download_file);
} else {
}
// RENAME
- if (mFile == null || downloading || uploading) {
+ if (mFile == null || synchronizing) {
toHide.add(R.id.action_rename_file);
} else {
}
// MOVE & COPY
- if (mFile == null || downloading || uploading) {
+ if (mFile == null || synchronizing) {
toHide.add(R.id.action_move);
toHide.add(R.id.action_copy);
} else {
}
// REMOVE
- if (mFile == null || downloading || uploading) {
+ if (mFile == null || synchronizing) {
toHide.add(R.id.action_remove_file);
} else {
}
// OPEN WITH (different to preview!)
- if (mFile == null || mFile.isFolder() || !mFile.isDown() || downloading || uploading) {
+ if (mFile == null || mFile.isFolder() || !mFile.isDown() || synchronizing) {
toHide.add(R.id.action_open_file_with);
} else {
toShow.add(R.id.action_open_file_with);
}
+ // CANCEL SYNCHRONIZATION
+ if (mFile == null || !synchronizing) {
+ toHide.add(R.id.action_cancel_sync);
- // CANCEL DOWNLOAD
- if (mFile == null || !downloading) {
- toHide.add(R.id.action_cancel_download);
} else {
- toShow.add(R.id.action_cancel_download);
+ toShow.add(R.id.action_cancel_sync);
}
- // CANCEL UPLOAD
- if (mFile == null || !uploading || mFile.isFolder()) {
- toHide.add(R.id.action_cancel_upload);
- } else {
- toShow.add(R.id.action_cancel_upload);
- }
-
- // SYNC FILE CONTENTS
- if (mFile == null || (!mFile.isFolder() && !mFile.isDown()) || downloading || uploading) {
+ // SYNC CONTENTS (BOTH FILE AND FOLDER)
+ if (mFile == null || (!mFile.isFolder() && !mFile.isDown()) || synchronizing) {
toHide.add(R.id.action_sync_file);
+
} else {
toShow.add(R.id.action_sync_file);
}
// SEND
boolean sendAllowed = (mContext != null &&
mContext.getString(R.string.send_files_to_other_apps).equalsIgnoreCase("on"));
- if (mFile == null || !sendAllowed || mFile.isFolder() || uploading || downloading) {
+ if (mFile == null || !sendAllowed || mFile.isFolder() || synchronizing) {
toHide.add(R.id.action_send_file);
} else {
toShow.add(R.id.action_send_file);
}
// FAVORITES
- if (mFile == null || downloading || uploading || mFile.isFolder() || mFile.isFavorite()) {
+ if (mFile == null || synchronizing || mFile.isFolder() || mFile.isFavorite()) {
toHide.add(R.id.action_favorite_file);
} else {
toShow.add(R.id.action_favorite_file);
}
// UNFAVORITES
- if (mFile == null || downloading || uploading || mFile.isFolder() || !mFile.isFavorite()) {
+ if (mFile == null || synchronizing || mFile.isFolder() || !mFile.isFavorite()) {
toHide.add(R.id.action_unfavorite_file);
} else {
toShow.add(R.id.action_unfavorite_file);
// for both files and folders
FileDownloaderBinder downloaderBinder = mFileActivity.getFileDownloaderBinder();
- FileUploaderBinder uploaderBinder = mFileActivity.getFileUploaderBinder();
if (downloaderBinder != null && downloaderBinder.isDownloading(account, file)) {
downloaderBinder.cancel(account, file);
mFileActivity.getStorageManager().saveFile(parent);
}
- } else if (uploaderBinder != null && uploaderBinder.isUploading(account, file)) {
+ }
+ FileUploaderBinder uploaderBinder = mFileActivity.getFileUploaderBinder();
+ if (uploaderBinder != null && uploaderBinder.isUploading(account, file)) {
uploaderBinder.cancel(account, file);
}
}
/**
* Entry point to add one or several files to the queue of downloads.
- * <p/>
+ *
* New downloads are added calling to startService(), resulting in a call to this method.
* This ensures the service will keep on working although the caller activity goes away.
*/
} else {
final Account account = intent.getParcelableExtra(EXTRA_ACCOUNT);
final OCFile file = intent.getParcelableExtra(EXTRA_FILE);
-
- /*Log_OC.v(
- "NOW " + TAG + ", thread " + Thread.currentThread().getName(),
- "Received request to download file"
- );*/
-
AbstractList<String> requestedDownloads = new Vector<String>();
try {
DownloadFileOperation newDownload = new DownloadFileOperation(account, file);
);
String downloadKey = putResult.first;
requestedDownloads.add(downloadKey);
- /*Log_OC.v(
- "NOW " + TAG + ", thread " + Thread.currentThread().getName(),
- "Download on " + file.getRemotePath() + " added to queue"
- );*/
// Store file on db with state 'downloading'
/*
* @param file A file in the queue of pending downloads
*/
public void cancel(Account account, OCFile file) {
- /*Log_OC.v(
- "NOW " + TAG + ", thread " + Thread.currentThread().getName(),
- "Received request to cancel download of " + file.getRemotePath()
- );
- Log_OC.v( "NOW " + TAG + ", thread " + Thread.currentThread().getName(),
- "Removing download of " + file.getRemotePath());*/
- Pair<DownloadFileOperation, String> removeResult =
- mPendingDownloads.remove(account, file.getRemotePath());
+ Pair<DownloadFileOperation, String> removeResult = mPendingDownloads.remove(account, file.getRemotePath());
DownloadFileOperation download = removeResult.first;
if (download != null) {
- /*Log_OC.v( "NOW " + TAG + ", thread " + Thread.currentThread().getName(),
- "Canceling returned download of " + file.getRemotePath());*/
download.cancel();
} else {
if (mCurrentDownload != null && mCurrentAccount != null &&
mCurrentDownload.getRemotePath().startsWith(file.getRemotePath()) &&
account.name.equals(mCurrentAccount.name)) {
- /*Log_OC.v( "NOW " + TAG + ", thread " + Thread.currentThread().getName(),
- "Canceling current sync as descendant: " + mCurrentDownload.getRemotePath());*/
mCurrentDownload.cancel();
}
}
}
/**
- * Cancels a pending or current upload for an account
+ * Cancels all the downloads for an account
*
- * @param account Owncloud accountName where the remote file will be stored.
+ * @param account ownCloud account.
*/
public void cancel(Account account) {
Log_OC.d(TAG, "Account= " + account.name);
OnDatatransferProgressListener listener, Account account, OCFile file
) {
if (account == null || file == null || listener == null) return;
- //String targetKey = buildKey(account, file.getRemotePath());
mBoundListeners.put(file.getFileId(), listener);
}
/**
* Removes a listener interested in the progress of the download for a concrete file.
*
- * @param listener Object to notify about progress of transfer.
- * @param account ownCloud account holding the file of interest.
- * @param file {@link OCFile} of interest for listener.
+ * @param listener Object to notify about progress of transfer.
+ * @param account ownCloud account holding the file of interest.
+ * @param file {@link OCFile} of interest for listener.
*/
public void removeDatatransferProgressListener(
OnDatatransferProgressListener listener, Account account, OCFile file
) {
if (account == null || file == null || listener == null) return;
- //String targetKey = buildKey(account, file.getRemotePath());
Long fileId = file.getFileId();
if (mBoundListeners.get(fileId) == listener) {
mBoundListeners.remove(fileId);
@Override
public void onTransferProgress(long progressRate, long totalTransferredSoFar,
long totalToTransfer, String fileName) {
- //String key = buildKey(mCurrentDownload.getAccount(),
- // mCurrentDownload.getFile().getRemotePath());
OnDatatransferProgressListener boundListener =
mBoundListeners.get(mCurrentDownload.getFile().getFileId());
if (boundListener != null) {
}
}
- /**
- * Review downloads and cancel it if its account doesn't exist
- */
- public void checkAccountOfCurrentDownload() {
- if (mCurrentDownload != null &&
- !AccountUtils.exists(mCurrentDownload.getAccount(), getApplicationContext())) {
- mCurrentDownload.cancel();
- }
- // The rest of downloads are cancelled when they try to start
- }
-
}
/**
* Download worker. Performs the pending downloads in the order they were requested.
- * <p/>
+
* Created with the Looper of a new thread, started in {@link FileUploader#onCreate()}.
*/
private static class ServiceHandler extends Handler {
private ServiceHandler mServiceHandler;
private IBinder mBinder;
private OwnCloudClient mUploadClient = null;
- private Account mLastAccount = null;
+ private Account mCurrentAccount = null;
private FileDataStorageManager mStorageManager;
private IndexedForest<UploadFileOperation> mPendingUploads = new IndexedForest<UploadFileOperation>();
}
/**
- * Builds a key for mPendingUploads from the account and file to upload
- *
- * @param account Account where the file to upload is stored
- * @param file File to upload
- */
- private String buildRemoteName(Account account, OCFile file) {
- return account.name + file.getRemotePath();
- }
-
- private String buildRemoteName(Account account, String remotePath) {
- return account.name + remotePath;
- }
-
- /**
* Checks if an ownCloud server version should support chunked uploads.
*
* @param version OwnCloud version instance corresponding to an ownCloud
* server.
* @return 'True' if the ownCloud server with version supports chunked
* uploads.
+ *
+ * TODO - move to OCClient
*/
private static boolean chunkedUploadIsSupported(OwnCloudVersion version) {
return (version != null && version.compareTo(OwnCloudVersion.owncloud_v4_5) >= 0);
files = new OCFile[localPaths.length];
for (int i = 0; i < localPaths.length; i++) {
files[i] = obtainNewOCFileToUpload(remotePaths[i], localPaths[i],
- ((mimeTypes != null) ? mimeTypes[i] : null), storageManager);
+ ((mimeTypes != null) ? mimeTypes[i] : null));
if (files[i] == null) {
// TODO @andomaex add failure Notification
return Service.START_NOT_STICKY;
/**
* Cancels a pending or current upload of a remote file.
*
- * @param account Owncloud account where the remote file will be stored.
- * @param file A file in the queue of pending uploads
+ * @param account ownCloud account where the remote file will be stored.
+ * @param file A file in the queue of pending uploads
*/
public void cancel(Account account, OCFile file) {
- UploadFileOperation upload;
- //synchronized (mPendingUploads) {
- Pair<UploadFileOperation, String> removeResult = mPendingUploads.remove(account, file.getRemotePath());
- upload = removeResult.first;
- //}
+ Pair<UploadFileOperation, String> removeResult = mPendingUploads.remove(account, file.getRemotePath());
+ UploadFileOperation upload = removeResult.first;
if (upload != null) {
upload.cancel();
+ } else {
+ if (mCurrentUpload != null && mCurrentAccount != null &&
+ mCurrentUpload.getRemotePath().startsWith(file.getRemotePath()) &&
+ account.name.equals(mCurrentAccount.name)) {
+ mCurrentUpload.cancel();
+ }
}
}
/**
- * Cancels a pending or current upload for an account
+ * Cancels all the uploads for an account
*
- * @param account Owncloud accountName where the remote file will be stored.
+ * @param account ownCloud account.
*/
public void cancel(Account account) {
Log_OC.d(TAG, "Account= " + account.name);
mBoundListeners.clear();
}
+
/**
* Returns True when the file described by 'file' is being uploaded to
* the ownCloud account 'account' or waiting for it
* @param file A file that could be in the queue of pending uploads
*/
public boolean isUploading(Account account, OCFile file) {
- /*
- if (account == null || file == null)
- return false;
- String targetKey = buildRemoteName(account, file);
- synchronized (mPendingUploads) {
- if (file.isFolder()) {
- // this can be slow if there are many uploads :(
- Iterator<String> it = mPendingUploads.keySet().iterator();
- boolean found = false;
- while (it.hasNext() && !found) {
- found = it.next().startsWith(targetKey);
- }
- return found;
- } else {
- return (mPendingUploads.containsKey(targetKey));
- }
- }*/
if (account == null || file == null) return false;
return (mPendingUploads.contains(account, file.getRemotePath()));
}
}
/**
- * Review uploads and cancel it if its account doesn't exist
+ * Builds a key for the map of listeners.
+ *
+ * TODO remove and replace key with file.getFileId() after changing current policy (upload file, then
+ * add to local database) to better policy (add to local database, then upload)
+ *
+ * @param account ownCloud account where the file to upload belongs.
+ * @param file File to upload
+ * @return Key
*/
- public void checkAccountOfCurrentUpload() {
- if (mCurrentUpload != null &&
- !AccountUtils.exists(mCurrentUpload.getAccount(), getApplicationContext())) {
- mCurrentUpload.cancel();
- }
- // The rest of uploads are cancelled when they try to start
+ private String buildRemoteName(Account account, OCFile file) {
+ return account.name + file.getRemotePath();
}
+
}
/**
try {
/// prepare client object to send the request to the ownCloud server
- if (mLastAccount == null || !mLastAccount.equals(mCurrentUpload.getAccount())) {
- mLastAccount = mCurrentUpload.getAccount();
+ if (mCurrentAccount == null || !mCurrentAccount.equals(mCurrentUpload.getAccount())) {
+ mCurrentAccount = mCurrentUpload.getAccount();
mStorageManager = new FileDataStorageManager(
- mLastAccount,
+ mCurrentAccount,
getContentResolver()
);
} // else, reuse storage manager from previous operation
// always get client from client manager, to get fresh credentials in case of update
- OwnCloudAccount ocAccount = new OwnCloudAccount(mLastAccount, this);
+ OwnCloudAccount ocAccount = new OwnCloudAccount(mCurrentAccount, this);
mUploadClient = OwnCloudClientManagerFactory.getDefaultSingleton().
getClientFor(ocAccount, this);
} catch (AccountsException e) {
Log_OC.e(TAG, "Error while trying to get autorization for " +
- mLastAccount.name, e);
+ mCurrentAccount.name, e);
uploadResult = new RemoteOperationResult(e);
} catch (IOException e) {
Log_OC.e(TAG, "Error while trying to get autorization for " +
- mLastAccount.name, e);
+ mCurrentAccount.name, e);
uploadResult = new RemoteOperationResult(e);
} finally {
Log_OC.v("NOW " + TAG + ", thread " + Thread.currentThread().getName(),
"Removing payload " + mCurrentUpload.getRemotePath());
Pair<UploadFileOperation, String> removeResult =
- mPendingUploads.removePayload(mLastAccount, mCurrentUpload.getRemotePath());
+ mPendingUploads.removePayload(mCurrentAccount, mCurrentUpload.getRemotePath());
/// notify result
notifyUploadResult(mCurrentUpload, uploadResult);
file.setRemoteId(remoteFile.getRemoteId());
}
- private OCFile obtainNewOCFileToUpload(String remotePath, String localPath, String mimeType,
- FileDataStorageManager storageManager) {
+ private OCFile obtainNewOCFileToUpload(String remotePath, String localPath, String mimeType) {
// MIME type
if (mimeType == null || mimeType.length() <= 0) {
* @param localPath Full path to a file in the local file system.
* @param mimeType MIME type of the file.
* @return true if is needed to add the pdf file extension to the file
+ *
+ * TODO - move to OCFile or Utils class
*/
private boolean isPdfFileFromContentProviderWithoutExtension(String localPath,
String mimeType) {
dialog.show(getFragmentManager(), FTAG_RENAME_FILE);
return true;
}
- case R.id.action_cancel_download:
- case R.id.action_cancel_upload: {
- ((FileDisplayActivity) mContainerActivity).cancelTransference(getFile());
+ case R.id.action_cancel_sync: {
+ ((FileDisplayActivity)mContainerActivity).cancelTransference(getFile());
return true;
}
case R.id.action_download_file:
mContainerActivity.getFileOperationsHelper().syncFile(mTargetFile);
return true;
}
- case R.id.action_cancel_download:
- case R.id.action_cancel_upload: {
- ((FileDisplayActivity) mContainerActivity).cancelTransference(mTargetFile);
+ case R.id.action_cancel_sync: {
+ ((FileDisplayActivity)mContainerActivity).cancelTransference(mTargetFile);
return true;
}
case R.id.action_see_details: {