X-Git-Url: http://git.linex4red.de/pub/Android/ownCloud.git/blobdiff_plain/68b52ddc5f0c75bec7887d390873e1295a36d235..c54d7e35d0efb3d1352ff6d1330cac185bef0a21:/src/com/owncloud/android/files/services/FileUploader.java diff --git a/src/com/owncloud/android/files/services/FileUploader.java b/src/com/owncloud/android/files/services/FileUploader.java index 071ac5f1..7c953b84 100644 --- a/src/com/owncloud/android/files/services/FileUploader.java +++ b/src/com/owncloud/android/files/services/FileUploader.java @@ -21,7 +21,6 @@ package com.owncloud.android.files.services; import java.io.File; -import java.io.IOException; import java.util.AbstractList; import java.util.HashMap; import java.util.Iterator; @@ -30,7 +29,6 @@ import java.util.Vector; import android.accounts.Account; import android.accounts.AccountManager; -import android.accounts.AccountsException; import android.accounts.OnAccountsUpdateListener; import android.app.NotificationManager; import android.app.PendingIntent; @@ -113,7 +111,7 @@ public class FileUploader extends Service private ServiceHandler mServiceHandler; private IBinder mBinder; private OwnCloudClient mUploadClient = null; - private Account mLastAccount = null; + private Account mCurrentAccount = null; private FileDataStorageManager mStorageManager; private IndexedForest mPendingUploads = new IndexedForest(); @@ -132,26 +130,14 @@ public class FileUploader extends Service } /** - * 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); @@ -281,7 +267,7 @@ public class FileUploader extends Service 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; @@ -389,24 +375,27 @@ public class FileUploader extends Service /** * 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 removeResult = mPendingUploads.remove(account, file.getRemotePath()); - upload = removeResult.first; - //} + Pair 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); @@ -425,6 +414,7 @@ public class FileUploader extends Service mBoundListeners.clear(); } + /** * Returns True when the file described by 'file' is being uploaded to * the ownCloud account 'account' or waiting for it @@ -436,23 +426,6 @@ public class FileUploader extends Service * @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 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())); } @@ -503,15 +476,19 @@ public class FileUploader extends Service } /** - * 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(); } + } /** @@ -555,8 +532,6 @@ public class FileUploader extends Service */ public void uploadFile(String uploadKey) { - Log_OC.v( "NOW " + TAG + ", thread " + Thread.currentThread().getName(), - "Getting upload of " + uploadKey); mCurrentUpload = mPendingUploads.get(uploadKey); if (mCurrentUpload != null) { @@ -570,16 +545,16 @@ public class FileUploader extends Service 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); @@ -592,33 +567,37 @@ public class FileUploader extends Service /// 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); if (uploadResult.isSuccess()) { saveUploadedFile(); + + } else if (uploadResult.getCode() == ResultCode.SYNC_CONFLICT) { + mStorageManager.saveConflict(mCurrentUpload.getFile(), + mCurrentUpload.getFile().getEtagInConflict()); } } else { uploadResult = grantResult; } - } catch (AccountsException e) { - Log_OC.e(TAG, "Error while trying to get autorization for " + - mLastAccount.name, e); - uploadResult = new RemoteOperationResult(e); - - } catch (IOException e) { - Log_OC.e(TAG, "Error while trying to get autorization for " + - mLastAccount.name, e); + } catch (Exception e) { + Log_OC.e(TAG, "Error uploading", e); uploadResult = new RemoteOperationResult(e); } finally { - Log_OC.v("NOW " + TAG + ", thread " + Thread.currentThread().getName(), - "Removing payload " + mCurrentUpload.getRemotePath()); - Pair removeResult = - mPendingUploads.removePayload(mLastAccount, mCurrentUpload.getRemotePath()); + Pair removeResult; + if (mCurrentUpload.wasRenamed()) { + removeResult = mPendingUploads.removePayload( + mCurrentAccount, + mCurrentUpload.getOldFile().getRemotePath() + ); + } else { + removeResult = mPendingUploads.removePayload( + mCurrentAccount, + mCurrentUpload.getRemotePath() + ); + } /// notify result notifyUploadResult(mCurrentUpload, uploadResult); @@ -697,7 +676,7 @@ public class FileUploader extends Service * synchronized with the server, specially the modification time and Etag * (where available) * - * TODO refactor this ugly thing + * TODO move into UploadFileOperation */ private void saveUploadedFile() { OCFile file = mCurrentUpload.getFile(); @@ -715,6 +694,8 @@ public class FileUploader extends Service if (result.isSuccess()) { updateOCFile(file, (RemoteFile) result.getData().get(0)); file.setLastSyncDateForProperties(syncDate); + } else { + Log_OC.e(TAG, "Error reading properties of file after successful upload; this is gonna hurt..."); } // / maybe this would be better as part of UploadFileOperation... or @@ -724,6 +705,7 @@ public class FileUploader extends Service if (oldFile.fileExists()) { oldFile.setStoragePath(null); mStorageManager.saveFile(oldFile); + mStorageManager.saveConflict(oldFile, null); } // else: it was just an automatic renaming due to a name // coincidence; nothing else is needed, the storagePath is right @@ -731,6 +713,10 @@ public class FileUploader extends Service } file.setNeedsUpdateThumbnail(true); mStorageManager.saveFile(file); + mStorageManager.saveConflict(file, null); + + mStorageManager.triggerMediaScan(file.getStoragePath()); + } private void updateOCFile(OCFile file, RemoteFile remoteFile) { @@ -739,12 +725,11 @@ public class FileUploader extends Service file.setMimetype(remoteFile.getMimeType()); file.setModificationTimestamp(remoteFile.getModifiedTimestamp()); file.setModificationTimestampAtLastSyncForData(remoteFile.getModifiedTimestamp()); - // file.setEtag(remoteFile.getEtag()); // TODO Etag, where available + file.setEtag(remoteFile.getEtag()); 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) { @@ -980,6 +965,8 @@ public class FileUploader extends Service * @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) {