/**
* Returns True when the file described by 'file' in the ownCloud account 'account'
* is downloading or waiting to download.
- * <p/>
+ *
* If 'file' is a directory, returns 'true' if any of its descendant files is downloading or
* waiting to download.
*
*/
private void downloadFile(String downloadKey) {
- /*Log_OC.v( "NOW " + TAG + ", thread " + Thread.currentThread().getName(),
- "Getting download of " + downloadKey);*/
mCurrentDownload = mPendingDownloads.get(downloadKey);
if (mCurrentDownload != null) {
// Detect if the account exists
if (AccountUtils.exists(mCurrentDownload.getAccount(), getApplicationContext())) {
Log_OC.d(TAG, "Account " + mCurrentDownload.getAccount().name + " exists");
+
notifyDownloadStart(mCurrentDownload);
RemoteOperationResult downloadResult = null;
/// perform the download
- /*Log_OC.v( "NOW " + TAG + ", thread " + Thread.currentThread().getName(),
- "Executing download of " + mCurrentDownload.getRemotePath());*/
downloadResult = mCurrentDownload.execute(mDownloadClient);
if (downloadResult.isSuccess()) {
saveDownloadedFile();
downloadResult = new RemoteOperationResult(e);
} finally {
- /*Log_OC.v( "NOW " + TAG + ", thread " + Thread.currentThread().getName(),
- "Removing payload " + mCurrentDownload.getRemotePath());*/
-
Pair<DownloadFileOperation, String> removeResult =
mPendingDownloads.removePayload(mCurrentAccount,
mCurrentDownload.getRemotePath());
/// notify result
notifyDownloadResult(mCurrentDownload, downloadResult);
- sendBroadcastDownloadFinished(mCurrentDownload, downloadResult,
- removeResult.second);
+ sendBroadcastDownloadFinished(mCurrentDownload, downloadResult, removeResult.second);
}
+
} else {
// Cancel the transfer
Log_OC.d(TAG, "Account " + mCurrentDownload.getAccount().toString() +
DownloadFileOperation download,
RemoteOperationResult downloadResult,
String unlinkedFromRemotePath) {
+
Intent end = new Intent(getDownloadFinishMessage());
end.putExtra(EXTRA_DOWNLOAD_RESULT, downloadResult.isSuccess());
end.putExtra(ACCOUNT_NAME, download.getAccount().name);
import java.util.Iterator;
import java.util.Map;
import java.util.Vector;
-import java.util.concurrent.ConcurrentHashMap;
-import java.util.concurrent.ConcurrentMap;
import android.accounts.Account;
import android.accounts.AccountManager;
import android.os.Message;
import android.os.Process;
import android.support.v4.app.NotificationCompat;
+import android.util.Pair;
import android.webkit.MimeTypeMap;
import com.owncloud.android.R;
public static final String EXTRA_REMOTE_PATH = "REMOTE_PATH";
public static final String EXTRA_OLD_REMOTE_PATH = "OLD_REMOTE_PATH";
public static final String EXTRA_OLD_FILE_PATH = "OLD_FILE_PATH";
+ public static final String EXTRA_LINKED_TO_PATH = "LINKED_TO";
public static final String ACCOUNT_NAME = "ACCOUNT_NAME";
public static final String KEY_FILE = "FILE";
private Account mLastAccount = null;
private FileDataStorageManager mStorageManager;
- private ConcurrentMap<String, UploadFileOperation> mPendingUploads =
- new ConcurrentHashMap<String, UploadFileOperation>();
+ private IndexedForest<UploadFileOperation> mPendingUploads = new IndexedForest<UploadFileOperation>();
private UploadFileOperation mCurrentUpload = null;
private NotificationManager mNotificationManager;
UploadFileOperation newUpload = null;
try {
for (int i = 0; i < files.length; i++) {
- uploadKey = buildRemoteName(account, files[i].getRemotePath());
- newUpload = new UploadFileOperation(account, files[i], chunked, isInstant,
+ newUpload = new UploadFileOperation(
+ account,
+ files[i],
+ chunked,
+ isInstant,
forceOverwrite, localAction,
- getApplicationContext());
+ getApplicationContext()
+ );
if (isInstant) {
newUpload.setRemoteFolderToBeCreated();
}
- // Grants that the file only upload once time
- mPendingUploads.putIfAbsent(uploadKey, newUpload);
-
newUpload.addDatatransferProgressListener(this);
- newUpload.addDatatransferProgressListener((FileUploaderBinder)mBinder);
+ newUpload.addDatatransferProgressListener((FileUploaderBinder) mBinder);
+ Pair<String, String> putResult = mPendingUploads.putIfAbsent(
+ account, files[i].getRemotePath(), newUpload
+ );
+ uploadKey = putResult.first;
requestedUploads.add(uploadKey);
}
msg.obj = requestedUploads;
mServiceHandler.sendMessage(msg);
}
- Log_OC.i(TAG, "mPendingUploads size:" + mPendingUploads.size());
return Service.START_NOT_STICKY;
}
*/
public void cancel(Account account, OCFile file) {
UploadFileOperation upload;
- synchronized (mPendingUploads) {
- upload = mPendingUploads.remove(buildRemoteName(account, file));
- }
+ //synchronized (mPendingUploads) {
+ Pair<UploadFileOperation, String> removeResult = mPendingUploads.remove(account, file.getRemotePath());
+ upload = removeResult.first;
+ //}
if (upload != null) {
upload.cancel();
}
}
}
// Cancel pending uploads
- cancelUploadForAccount(account.name);
+ cancelUploadsForAccount(account);
}
public void clearListeners() {
* @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);
} else {
return (mPendingUploads.containsKey(targetKey));
}
- }
+ }*/
+ if (account == null || file == null) return false;
+ return (mPendingUploads.contains(account, file.getRemotePath()));
}
/**
* Core upload method: sends the file(s) to upload
*
- * @param uploadKey Key to access the upload to perform, contained in
- * mPendingUploads
+ * @param uploadKey Key to access the upload to perform, contained in mPendingUploads
*/
public void uploadFile(String uploadKey) {
- synchronized (mPendingUploads) {
- mCurrentUpload = mPendingUploads.get(uploadKey);
- }
+ Log_OC.v( "NOW " + TAG + ", thread " + Thread.currentThread().getName(),
+ "Getting upload of " + uploadKey);
+ mCurrentUpload = mPendingUploads.get(uploadKey);
if (mCurrentUpload != null) {
-
// Detect if the account exists
if (AccountUtils.exists(mCurrentUpload.getAccount(), getApplicationContext())) {
Log_OC.d(TAG, "Account " + mCurrentUpload.getAccount().name + " exists");
RemoteOperationResult uploadResult = null, grantResult;
try {
- /// prepare client object to send requests to the ownCloud server
- if (mUploadClient == null ||
- !mLastAccount.equals(mCurrentUpload.getAccount())) {
+ /// prepare client object to send the request to the ownCloud server
+ if (mLastAccount == null || !mLastAccount.equals(mCurrentUpload.getAccount())) {
mLastAccount = mCurrentUpload.getAccount();
- mStorageManager =
- new FileDataStorageManager(mLastAccount, getContentResolver());
- OwnCloudAccount ocAccount = new OwnCloudAccount(mLastAccount, this);
- mUploadClient = OwnCloudClientManagerFactory.getDefaultSingleton().
- getClientFor(ocAccount, this);
- }
+ mStorageManager = new FileDataStorageManager(
+ mLastAccount,
+ 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);
+ mUploadClient = OwnCloudClientManagerFactory.getDefaultSingleton().
+ getClientFor(ocAccount, this);
+
/// check the existence of the parent folder for the file to upload
String remoteParentPath = new File(mCurrentUpload.getRemotePath()).getParent();
/// perform the upload
if (grantResult.isSuccess()) {
+ Log_OC.v( "NOW " + TAG + ", thread " + Thread.currentThread().getName(),
+ "Executing upload of " + mCurrentUpload.getRemotePath());
OCFile parent = mStorageManager.getFileByPath(remoteParentPath);
mCurrentUpload.getFile().setParentId(parent.getFileId());
uploadResult = mCurrentUpload.execute(mUploadClient);
uploadResult = new RemoteOperationResult(e);
} finally {
- synchronized (mPendingUploads) {
- mPendingUploads.remove(uploadKey);
- Log_OC.i(TAG, "Remove CurrentUploadItem from pending upload Item Map.");
- }
- if (uploadResult != null && uploadResult.isException()) {
- // enforce the creation of a new client object for next uploads;
- // this grant that a new socket will be created in the future if
- // the current exception is due to an abrupt lose of network connection
- mUploadClient = null;
- }
- }
+ Log_OC.v("NOW " + TAG + ", thread " + Thread.currentThread().getName(),
+ "Removing payload " + mCurrentUpload.getRemotePath());
+ Pair<UploadFileOperation, String> removeResult =
+ mPendingUploads.removePayload(mLastAccount, mCurrentUpload.getRemotePath());
+
+ /// notify result
+ notifyUploadResult(mCurrentUpload, uploadResult);
- /// notify result
- notifyUploadResult(uploadResult, mCurrentUpload);
- sendFinalBroadcast(mCurrentUpload, uploadResult);
+ sendBroadcastUploadFinished(mCurrentUpload, uploadResult, removeResult.second);
+ }
} else {
// Cancel the transfer
Log_OC.d(TAG, "Account " + mCurrentUpload.getAccount().toString() +
" doesn't exist");
- cancelUploadForAccount(mCurrentUpload.getAccount().name);
+ cancelUploadsForAccount(mCurrentUpload.getAccount());
}
}
/**
* Updates the status notification with the result of an upload operation.
*
- * @param uploadResult Result of the upload operation.
- * @param upload Finished upload operation
+ * @param uploadResult Result of the upload operation.
+ * @param upload Finished upload operation
*/
- private void notifyUploadResult(
- RemoteOperationResult uploadResult, UploadFileOperation upload) {
+ private void notifyUploadResult(UploadFileOperation upload,
+ RemoteOperationResult uploadResult) {
Log_OC.d(TAG, "NotifyUploadResult with resultCode: " + uploadResult.getCode());
// / cancelled operation or success -> silent removal of progress notification
mNotificationManager.cancel(R.string.uploader_upload_in_progress_ticker);
* Sends a broadcast in order to the interested activities can update their
* view
*
- * @param upload Finished upload operation
- * @param uploadResult Result of the upload operation
+ * @param upload Finished upload operation
+ * @param uploadResult Result of the upload operation
+ * @param unlinkedFromRemotePath Path in the uploads tree where the upload was unlinked from
*/
- private void sendFinalBroadcast(UploadFileOperation upload, RemoteOperationResult uploadResult) {
+ private void sendBroadcastUploadFinished(
+ UploadFileOperation upload,
+ RemoteOperationResult uploadResult,
+ String unlinkedFromRemotePath) {
+
Intent end = new Intent(getUploadFinishMessage());
end.putExtra(EXTRA_REMOTE_PATH, upload.getRemotePath()); // real remote
// path, after
end.putExtra(EXTRA_OLD_FILE_PATH, upload.getOriginalStoragePath());
end.putExtra(ACCOUNT_NAME, upload.getAccount().name);
end.putExtra(EXTRA_UPLOAD_RESULT, uploadResult.isSuccess());
+ if (unlinkedFromRemotePath != null) {
+ end.putExtra(EXTRA_LINKED_TO_PATH, unlinkedFromRemotePath);
+ }
+
sendStickyBroadcast(end);
}
/**
* Remove uploads of an account
- * @param accountName Name of an OC account
+ *
+ * @param account Downloads account to remove
*/
- private void cancelUploadForAccount(String accountName){
- // this can be slow if there are many uploads :(
- Iterator<String> it = mPendingUploads.keySet().iterator();
- Log_OC.d(TAG, "Number of pending updloads= " + mPendingUploads.size());
- while (it.hasNext()) {
- String key = it.next();
- Log_OC.d(TAG, "mPendingUploads CANCELLED " + key);
- if (key.startsWith(accountName)) {
- synchronized (mPendingUploads) {
- mPendingUploads.remove(key);
- }
- }
- }
+ private void cancelUploadsForAccount(Account account){
+ // Cancel pending uploads
+ mPendingUploads.remove(account);
}
}
mTransferServiceGetter.getFileUploaderBinder();\r
OperationsServiceBinder opsBinder =\r
mTransferServiceGetter.getOperationsServiceBinder();\r
- boolean downloading = (downloaderBinder != null &&\r
- downloaderBinder.isDownloading(mAccount, file));\r
- boolean uploading = (uploaderBinder != null &&\r
- uploaderBinder.isUploading(mAccount, file));\r
- boolean synchronizing = (opsBinder != null &&\r
- opsBinder.isSynchronizing(mAccount, file.getRemotePath()));\r
\r
localStateView.setVisibility(View.INVISIBLE); // default first\r
\r
if (file.isFolder()) {\r
- if (synchronizing || downloading || uploading) {\r
+ if ( //synchronizing\r
+ (opsBinder != null &&\r
+ opsBinder.isSynchronizing(mAccount, file.getRemotePath())) ||\r
+ // downloading\r
+ (downloaderBinder != null &&\r
+ downloaderBinder.isDownloading(mAccount, file)) ||\r
+ // uploading\r
+ (uploaderBinder != null &&\r
+ uploaderBinder.isUploading(mAccount, file))\r
+ ) {\r
+\r
localStateView.setImageResource(R.drawable.synchronizing_file_indicator);\r
localStateView.setVisibility(View.VISIBLE);\r
}\r
\r
- } else if (synchronizing) {\r
+ } else if ( //synchronizing\r
+ opsBinder != null &&\r
+ opsBinder.isSynchronizing(mAccount, file.getRemotePath())\r
+ ) {\r
localStateView.setImageResource(R.drawable.synchronizing_file_indicator);\r
localStateView.setVisibility(View.VISIBLE);\r
\r
- } else if (downloading) {\r
+ } else if ( // downloading\r
+ downloaderBinder != null &&\r
+ downloaderBinder.isDownloading(mAccount, file)\r
+ ) {\r
localStateView.setImageResource(R.drawable.downloading_file_indicator);\r
localStateView.setVisibility(View.VISIBLE);\r
\r
- } else if (uploading) {\r
+ } else if (//uploading\r
+ uploaderBinder != null &&\r
+ uploaderBinder.isUploading(mAccount, file)\r
+ ) {\r
localStateView.setImageResource(R.drawable.uploading_file_indicator);\r
localStateView.setVisibility(View.VISIBLE);\r
\r